aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-11-10 15:43:13 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2017-11-10 15:43:13 +0100
commit127ef36981ebdfbe3be0f8df710090642a2a4abe (patch)
treec68a1dc595dca3d5343f87ec39f6fc2f1e5794a3
parent93814e2d690f7ccae4d87365b66d05cfa4a11576 (diff)
downloadgcc-127ef36981ebdfbe3be0f8df710090642a2a4abe.zip
gcc-127ef36981ebdfbe3be0f8df710090642a2a4abe.tar.gz
gcc-127ef36981ebdfbe3be0f8df710090642a2a4abe.tar.bz2
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
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/gimple-ssa-store-merging.c25
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/opt/pr82929.C30
-rw-r--r--gcc/testsuite/gcc.dg/pr82929.c18
5 files changed, 82 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index de86f33..57a7a1e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2017-11-10 Jakub Jelinek <jakub@redhat.com>
+
+ 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 <mliska@suse.cz>
* coverage.c (coverage_init): Stream information about
diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c
index a5ee7aa..40f7c98 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 dc6799a..72dea0a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2017-11-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/82929
+ * gcc.dg/pr82929.c: New test.
+ * g++.dg/opt/pr82929.C: New test.
+
2017-11-10 Christophe Lyon <christophe.lyon@linaro.org>
* 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 0000000..572f491
--- /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 <int _Nw> 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 <int _Nb> 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 0000000..afe9394
--- /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" } } */