diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c8dd6d0c613..cf37d814a66 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2020-02-26 Jakub Jelinek + + PR tree-optimization/93820 + * gimple-ssa-store-merging.c (check_no_overlap): Change RHS_CODE + argument to ALL_INTEGER_CST_P boolean. + (imm_store_chain_info::try_coalesce_bswap): Adjust caller. + (imm_store_chain_info::coalesce_immediate_stores): Likewise. Handle + adjacent INTEGER_CST store into merged_store->only_constants like + overlapping one. + 2020-02-25 Christophe Lyon Backport from mainline diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c index 4a8cf6f847f..550f782813b 100644 --- a/gcc/gimple-ssa-store-merging.c +++ b/gcc/gimple-ssa-store-merging.c @@ -2375,8 +2375,9 @@ gather_bswap_load_refs (vec *refs, tree val) /* Check if there are any stores in M_STORE_INFO after index I (where M_STORE_INFO must be sorted by sort_by_bitpos) that overlap a potential group ending with END that have their order - smaller than LAST_ORDER. RHS_CODE is the kind of store in the - group. Return true if there are no such stores. + smaller than LAST_ORDER. ALL_INTEGER_CST_P is true if + all the stores already merged and the one under consideration + have rhs_code of INTEGER_CST. Return true if there are no such stores. Consider: MEM[(long long int *)p_28] = 0; MEM[(long long int *)p_28 + 8B] = 0; @@ -2399,13 +2400,13 @@ gather_bswap_load_refs (vec *refs, tree val) the MEM[(long long int *)p_28 + 8B] = 0; would now be before it, so we need to refuse merging MEM[(long long int *)p_28 + 8B] = 0; into the group. That way it will be its own store group and will - not be touched. If RHS_CODE is INTEGER_CST and there are overlapping + not be touched. If ALL_INTEGER_CST_P and there are overlapping INTEGER_CST stores, those are mergeable using merge_overlapping, so don't return false for those. */ static bool check_no_overlap (vec m_store_info, unsigned int i, - enum tree_code rhs_code, unsigned int last_order, + bool all_integer_cst_p, unsigned int last_order, unsigned HOST_WIDE_INT end) { unsigned int len = m_store_info.length (); @@ -2415,7 +2416,7 @@ check_no_overlap (vec m_store_info, unsigned int i, if (info->bitpos >= end) break; if (info->order < last_order - && (rhs_code != INTEGER_CST || info->rhs_code != INTEGER_CST)) + && (!all_integer_cst_p || info->rhs_code != INTEGER_CST)) return false; } return true; @@ -2568,7 +2569,7 @@ imm_store_chain_info::try_coalesce_bswap (merged_store_group *merged_store, if (n.base_addr == NULL_TREE && !is_gimple_val (n.src)) return false; - if (!check_no_overlap (m_store_info, last, LROTATE_EXPR, last_order, end)) + if (!check_no_overlap (m_store_info, last, false, last_order, end)) return false; /* Don't handle memory copy this way if normal non-bswap processing @@ -2709,7 +2710,14 @@ imm_store_chain_info::coalesce_immediate_stores () |---store 2---| Overlapping stores. */ else if (IN_RANGE (info->bitpos, merged_store->start, - merged_store->start + merged_store->width - 1)) + merged_store->start + merged_store->width - 1) + /* |---store 1---||---store 2---| + Handle also the consecutive INTEGER_CST stores case here, + as we have here the code to deal with overlaps. */ + || (info->bitregion_start <= merged_store->bitregion_end + && info->rhs_code == INTEGER_CST + && merged_store->only_constants + && merged_store->can_be_merged_into (info))) { /* Only allow overlapping stores of constants. */ if (info->rhs_code == INTEGER_CST && merged_store->only_constants) @@ -2719,8 +2727,7 @@ imm_store_chain_info::coalesce_immediate_stores () unsigned HOST_WIDE_INT end = MAX (merged_store->start + merged_store->width, info->bitpos + info->bitsize); - if (check_no_overlap (m_store_info, i, INTEGER_CST, - last_order, end)) + if (check_no_overlap (m_store_info, i, true, last_order, end)) { /* check_no_overlap call above made sure there are no overlapping stores with non-INTEGER_CST rhs_code @@ -2873,7 +2880,7 @@ imm_store_chain_info::coalesce_immediate_stores () std::swap (info->ops[0], info->ops[1]); info->ops_swapped_p = true; } - if (check_no_overlap (m_store_info, i, info->rhs_code, + if (check_no_overlap (m_store_info, i, false, MAX (merged_store->last_order, info->order), MAX (merged_store->start + merged_store->width, info->bitpos + info->bitsize))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 86bc08d4bb7..100489e1201 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-02-26 Jakub Jelinek + + PR tree-optimization/93820 + * gcc.dg/pr93820.c: New test. + 2020-02-26 Jakub Jelinek PR c++/93905 diff --git a/gcc/testsuite/gcc.dg/pr93820.c b/gcc/testsuite/gcc.dg/pr93820.c new file mode 100644 index 00000000000..98d8c20a178 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr93820.c @@ -0,0 +1,26 @@ +/* PR tree-optimization/93820 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-tree-dse" } */ + +typedef int v4si __attribute__((vector_size(4 * sizeof (int)))); +int a[10]; + +__attribute__((noipa)) int +foo (int *p) +{ + a[6] = *p; + a[4] = 1; + *(((v4si *)&a[0]) + 1) = (v4si) { 0, 0, 0, 0 }; + a[3] = 0; +} + +int +main () +{ + int i = 0; + foo (&i); + for (i = 0; i < 10; i++) + if (a[i]) + __builtin_abort (); + return 0; +}