Hi!

The following testcase fails because SLP creates
vect_something = {&c, &c};
stmt but update addresses taken after parloop doesn't discover the
ADDR_EXPRs in the ctor, thus TREE_ADDRESSABLE is dropped from c.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux.
Committing to trunk, will backport to 4.6 soon.

2011-08-03  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/49948
        * gimple.c (walk_stmt_load_store_addr_ops): Walk CONSTRUCTOR elements.

        * gcc.dg/pr49948.c: New test.

--- gcc/gimple.c.jj     2011-06-23 10:13:58.000000000 +0200
+++ gcc/gimple.c        2011-08-03 15:38:42.000000000 +0200
@@ -5257,6 +5257,20 @@ walk_stmt_load_store_addr_ops (gimple st
                   && TREE_CODE (OBJ_TYPE_REF_OBJECT (rhs)) == ADDR_EXPR)
            ret |= visit_addr (stmt, TREE_OPERAND (OBJ_TYPE_REF_OBJECT (rhs),
                                                   0), data);
+         else if (TREE_CODE (rhs) == CONSTRUCTOR)
+           {
+             unsigned int ix;
+             tree val;
+
+             FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), ix, val)
+               if (TREE_CODE (val) == ADDR_EXPR)
+                 ret |= visit_addr (stmt, TREE_OPERAND (val, 0), data);
+               else if (TREE_CODE (val) == OBJ_TYPE_REF
+                        && TREE_CODE (OBJ_TYPE_REF_OBJECT (val)) == ADDR_EXPR)
+                 ret |= visit_addr (stmt,
+                                    TREE_OPERAND (OBJ_TYPE_REF_OBJECT (val),
+                                                  0), data);
+           }
           lhs = gimple_assign_lhs (stmt);
          if (TREE_CODE (lhs) == TARGET_MEM_REF
               && TREE_CODE (TMR_BASE (lhs)) == ADDR_EXPR)
--- gcc/testsuite/gcc.dg/pr49948.c.jj   2011-08-03 15:41:38.000000000 +0200
+++ gcc/testsuite/gcc.dg/pr49948.c      2011-08-03 15:40:51.000000000 +0200
@@ -0,0 +1,22 @@
+/* PR tree-optimization/49948 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -ftree-parallelize-loops=2" } */
+
+extern int a, *b;
+int
+foo (void)
+{
+  int c, d = 8, *e[8], i;
+  if (a <= 7)
+    {
+      for (i = 0; i < 8; ++i)
+       e[i] = &c;
+      while (--d)
+       {
+         a = 0;
+         b = e[0];
+       }
+      return 0;
+    }
+  return b == &d;
+}

        Jakub

Reply via email to