From: Jakub Jelinek Date: Fri, 10 Nov 2017 14:43:13 +0000 (+0100) Subject: re PR tree-optimization/82929 (r254579 causes ICE: tree check: expected ssa_name... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=127ef36981ebdfbe3be0f8df710090642a2a4abe;p=gcc.git re PR tree-optimization/82929 (r254579 causes ICE: tree check: expected ssa_name, have array_ref in has_single_use, at ssa-iterators.h:400) PR tree-optimization/82929 * gimple-ssa-store-merging.c (struct store_immediate_info): Add ops_swapped_p non-static data member. (store_immediate_info::store_immediate_info): Clear it. (imm_store_chain_info::coalesce_immediate_stores): If swapping ops set ops_swapped_p. (count_multiple_uses): Handle ops_swapped_p. * gcc.dg/pr82929.c: New test. * g++.dg/opt/pr82929.C: New test. From-SVN: r254628 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index de86f33961b..57a7a1e9045 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2017-11-10 Jakub Jelinek + + PR tree-optimization/82929 + * gimple-ssa-store-merging.c (struct store_immediate_info): Add + ops_swapped_p non-static data member. + (store_immediate_info::store_immediate_info): Clear it. + (imm_store_chain_info::coalesce_immediate_stores): If swapping + ops set ops_swapped_p. + (count_multiple_uses): Handle ops_swapped_p. + 2017-11-10 Martin Liska * coverage.c (coverage_init): Stream information about diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c index a5ee7aa3943..40f7c9843f6 100644 --- a/gcc/gimple-ssa-store-merging.c +++ b/gcc/gimple-ssa-store-merging.c @@ -209,7 +209,11 @@ struct store_immediate_info /* INTEGER_CST for constant stores, MEM_REF for memory copy or BIT_*_EXPR for logical bitwise operation. */ enum tree_code rhs_code; + /* True if BIT_{AND,IOR,XOR}_EXPR result is inverted before storing. */ bool bit_not_p; + /* True if ops have been swapped and thus ops[1] represents + rhs1 of BIT_{AND,IOR,XOR}_EXPR and ops[0] represents rhs2. */ + bool ops_swapped_p; /* Operands. For BIT_*_EXPR rhs_code both operands are used, otherwise just the first one. */ store_operand_info ops[2]; @@ -231,7 +235,8 @@ store_immediate_info::store_immediate_info (unsigned HOST_WIDE_INT bs, const store_operand_info &op0r, const store_operand_info &op1r) : bitsize (bs), bitpos (bp), bitregion_start (brs), bitregion_end (bre), - stmt (st), order (ord), rhs_code (rhscode), bit_not_p (bitnotp) + stmt (st), order (ord), rhs_code (rhscode), bit_not_p (bitnotp), + ops_swapped_p (false) #if __cplusplus >= 201103L , ops { op0r, op1r } { @@ -1189,7 +1194,10 @@ imm_store_chain_info::coalesce_immediate_stores () == info->bitpos - infof->bitpos) && operand_equal_p (info->ops[1].base_addr, infof->ops[0].base_addr, 0)) - std::swap (info->ops[0], info->ops[1]); + { + std::swap (info->ops[0], info->ops[1]); + info->ops_swapped_p = true; + } if ((!infof->ops[0].base_addr || compatible_load_p (merged_store, info, base_addr, 0)) && (!infof->ops[1].base_addr @@ -1413,18 +1421,21 @@ count_multiple_uses (store_immediate_info *info) stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt)); /* stmt is now the BIT_*_EXPR. */ if (!has_single_use (gimple_assign_rhs1 (stmt))) - ret += 1 + info->ops[0].bit_not_p; - else if (info->ops[0].bit_not_p) + ret += 1 + info->ops[info->ops_swapped_p].bit_not_p; + else if (info->ops[info->ops_swapped_p].bit_not_p) { gimple *stmt2 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt)); if (!has_single_use (gimple_assign_rhs1 (stmt2))) ++ret; } if (info->ops[1].base_addr == NULL_TREE) - return ret; + { + gcc_checking_assert (!info->ops_swapped_p); + return ret; + } if (!has_single_use (gimple_assign_rhs2 (stmt))) - ret += 1 + info->ops[1].bit_not_p; - else if (info->ops[1].bit_not_p) + ret += 1 + info->ops[1 - info->ops_swapped_p].bit_not_p; + else if (info->ops[1 - info->ops_swapped_p].bit_not_p) { gimple *stmt2 = SSA_NAME_DEF_STMT (gimple_assign_rhs2 (stmt)); if (!has_single_use (gimple_assign_rhs1 (stmt2))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dc6799a476c..72dea0a92a0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2017-11-10 Jakub Jelinek + + PR tree-optimization/82929 + * gcc.dg/pr82929.c: New test. + * g++.dg/opt/pr82929.C: New test. + 2017-11-10 Christophe Lyon * lib/target-supports.exp (check_effective_target_arm_soft_ok): diff --git a/gcc/testsuite/g++.dg/opt/pr82929.C b/gcc/testsuite/g++.dg/opt/pr82929.C new file mode 100644 index 00000000000..572f4914815 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr82929.C @@ -0,0 +1,30 @@ +// PR tree-optimization/82929 +// { dg-do compile } +// { dg-options "-O2" } + +template struct A { + long _M_w[_Nw]; + void m_fn1(A p1) { + for (int a = 0;; a++) + _M_w[a] &= p1._M_w[a]; + } + void m_fn2() { + for (int b = 0; b < _Nw; b++) + _M_w[b] = ~_M_w[b]; + } +}; +template struct C : A<_Nb / (8 * 8)> { + void operator&=(C p1) { this->m_fn1(p1); } + C m_fn3() { + this->m_fn2(); + return *this; + } + C operator~() { return C(*this).m_fn3(); } +}; +struct B { + C<192> Value; +}; +void fn1(C<192> &p1) { + B c; + p1 &= ~c.Value; +} diff --git a/gcc/testsuite/gcc.dg/pr82929.c b/gcc/testsuite/gcc.dg/pr82929.c new file mode 100644 index 00000000000..afe9394ab31 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr82929.c @@ -0,0 +1,18 @@ +/* PR tree-optimization/82929 */ +/* { dg-do compile { target store_merge } } */ +/* { dg-options "-O2 -fdump-tree-store-merging" } */ + +void +foo (short *p, short *q, short *r) +{ + short a = q[0]; + short b = q[1]; + short c = ~a; + short d = r[0]; + short e = r[1]; + short f = ~b; + p[0] = c & d; + p[1] = e & f; +} + +/* { dg-final { scan-tree-dump-times "Merging successful" 1 "store-merging" } } */