re PR tree-optimization/82929 (r254579 causes ICE: tree check: expected ssa_name...
authorJakub Jelinek <jakub@redhat.com>
Fri, 10 Nov 2017 14:43:13 +0000 (15:43 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 10 Nov 2017 14:43:13 +0000 (15:43 +0100)
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

gcc/ChangeLog
gcc/gimple-ssa-store-merging.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr82929.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr82929.c [new file with mode: 0644]

index de86f33961bec514867bf2fa6be7ee03e0f32072..57a7a1e904504cef33bd8829afcd9bfdac60b349 100644 (file)
@@ -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
index a5ee7aa3943c89091ae58feeca3d80034df79583..40f7c9843f643826898376ea0f76551275aa8780 100644 (file)
@@ -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)))
index dc6799a476cc5844f90d1eab636f7970b873db54..72dea0a92a01ebe985ec8e9a3df9753092b0d78e 100644 (file)
@@ -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 (file)
index 0000000..572f491
--- /dev/null
@@ -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 (file)
index 0000000..afe9394
--- /dev/null
@@ -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" } } */