re PR tree-optimization/56448 (cc1 hangs on volatile array with -O or above)
authorJakub Jelinek <jakub@redhat.com>
Tue, 26 Feb 2013 10:00:31 +0000 (11:00 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 26 Feb 2013 10:00:31 +0000 (11:00 +0100)
PR tree-optimization/56448
* fold-const.c (operand_equal_p) <case tcc_reference>: Don't look at
TREE_SIDE_EFFECTS if flags contain OEP_CONSTANT_ADDRESS_OF.
Clear OEP_CONSTANT_ADDRESS_OF from flags before recursing on second or
later operands of the references, or even first operand for
INDIRECT_REF, TARGET_MEM_REF or MEM_REF.

* gcc.c-torture/compile/pr56448.c: New test.

From-SVN: r196278

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr56448.c [new file with mode: 0644]

index 0fc1478c3deaeaadfcf05f79b57614aed0774dfe..7b9b547b57a61c64506f4af0d70da0c5c8d56621 100644 (file)
@@ -1,5 +1,12 @@
 2013-02-26  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/56448
+       * fold-const.c (operand_equal_p) <case tcc_reference>: Don't look at
+       TREE_SIDE_EFFECTS if flags contain OEP_CONSTANT_ADDRESS_OF.
+       Clear OEP_CONSTANT_ADDRESS_OF from flags before recursing on second or
+       later operands of the references, or even first operand for
+       INDIRECT_REF, TARGET_MEM_REF or MEM_REF.
+
        PR tree-optimization/56443
        * tree-vect-stmts.c (get_vectype_for_scalar_type_and_size): For
        overaligned types, pass TYPE_UNSIGNED (scalar_type) as second argument
index 5acb4ad005944fb7bc3e53d48118fe2ec40fa608..26cfc0e83e430c2a71c6c242a00602cab5b40e36 100644 (file)
@@ -2542,19 +2542,25 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
 
     case tcc_reference:
       /* If either of the pointer (or reference) expressions we are
-        dereferencing contain a side effect, these cannot be equal.  */
-      if (TREE_SIDE_EFFECTS (arg0)
-         || TREE_SIDE_EFFECTS (arg1))
+        dereferencing contain a side effect, these cannot be equal,
+        but their addresses can be.  */
+      if ((flags & OEP_CONSTANT_ADDRESS_OF) == 0
+         && (TREE_SIDE_EFFECTS (arg0)
+             || TREE_SIDE_EFFECTS (arg1)))
        return 0;
 
       switch (TREE_CODE (arg0))
        {
        case INDIRECT_REF:
+         flags &= ~OEP_CONSTANT_ADDRESS_OF;
+         return OP_SAME (0);
+
        case REALPART_EXPR:
        case IMAGPART_EXPR:
          return OP_SAME (0);
 
        case TARGET_MEM_REF:
+         flags &= ~OEP_CONSTANT_ADDRESS_OF;
          /* Require equal extra operands and then fall through to MEM_REF
             handling of the two common operands.  */
          if (!OP_SAME_WITH_NULL (2)
@@ -2563,6 +2569,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
            return 0;
          /* Fallthru.  */
        case MEM_REF:
+         flags &= ~OEP_CONSTANT_ADDRESS_OF;
          /* Require equal access sizes, and similar pointer types.
             We can have incomplete types for array references of
             variable-sized arrays from the Fortran frontent
@@ -2581,22 +2588,28 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
          /* Operands 2 and 3 may be null.
             Compare the array index by value if it is constant first as we
             may have different types but same value here.  */
-         return (OP_SAME (0)
-                 && (tree_int_cst_equal (TREE_OPERAND (arg0, 1),
-                                         TREE_OPERAND (arg1, 1))
-                     || OP_SAME (1))
+         if (!OP_SAME (0))
+           return 0;
+         flags &= ~OEP_CONSTANT_ADDRESS_OF;
+         return ((tree_int_cst_equal (TREE_OPERAND (arg0, 1),
+                                      TREE_OPERAND (arg1, 1))
+                  || OP_SAME (1))
                  && OP_SAME_WITH_NULL (2)
                  && OP_SAME_WITH_NULL (3));
 
        case COMPONENT_REF:
          /* Handle operand 2 the same as for ARRAY_REF.  Operand 0
             may be NULL when we're called to compare MEM_EXPRs.  */
-         return OP_SAME_WITH_NULL (0)
-                && OP_SAME (1)
-                && OP_SAME_WITH_NULL (2);
+         if (!OP_SAME_WITH_NULL (0))
+           return 0;
+         flags &= ~OEP_CONSTANT_ADDRESS_OF;
+         return OP_SAME (1) && OP_SAME_WITH_NULL (2);
 
        case BIT_FIELD_REF:
-         return OP_SAME (0) && OP_SAME (1) && OP_SAME (2);
+         if (!OP_SAME (0))
+           return 0;
+         flags &= ~OEP_CONSTANT_ADDRESS_OF;
+         return OP_SAME (1) && OP_SAME (2);
 
        default:
          return 0;
index 8356fa46502afab210fb25ef7e1a9266d6cb7d80..1da7b6fe03a30df173d82d84f1a67e2b9f1296e8 100644 (file)
@@ -1,5 +1,8 @@
 2013-02-26  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/56448
+       * gcc.c-torture/compile/pr56448.c: New test.
+
        PR tree-optimization/56443
        * gcc.dg/torture/pr56443.c: New test.
 
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr56448.c b/gcc/testsuite/gcc.c-torture/compile/pr56448.c
new file mode 100644 (file)
index 0000000..f10da6c
--- /dev/null
@@ -0,0 +1,14 @@
+/* PR tree-optimization/56448 */
+
+volatile int a[1];
+int b;
+
+void
+foo ()
+{
+  for (;;)
+    {
+      int *c[3][6] = { 0, 0, 0, &b, 0, 0, 0, 0, &b, 0, 0, 0, 0, 0, 0, 0, &b, (int *) &a[0] };
+      b = *c[2][5];
+    }
+}