re PR tree-optimization/58653 (wrong code (segfaults) at -O3 on x86_64-linux-gnu...
authorRichard Biener <rguenther@suse.de>
Wed, 6 Nov 2013 15:00:16 +0000 (15:00 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 6 Nov 2013 15:00:16 +0000 (15:00 +0000)
2013-11-06  Richard Biener  <rguenther@suse.de>

PR tree-optimization/58653
* tree-predcom.c (ref_at_iteration): Rewrite to generate
a MEM_REF.
(prepare_initializers_chain): Adjust.

* gcc.dg/tree-ssa/predcom-6.c: New testcase.
* gcc.dg/tree-ssa/predcom-7.c: Likewise.

From-SVN: r204458

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/predcom-6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/predcom-7.c [new file with mode: 0644]
gcc/tree-predcom.c

index 7465c4a..9d45b0c 100644 (file)
@@ -1,3 +1,10 @@
+2013-11-06  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/58653
+       * tree-predcom.c (ref_at_iteration): Rewrite to generate
+       a MEM_REF.
+       (prepare_initializers_chain): Adjust.
+
 2013-11-06  Andrew MacLeod  <amacleod@redhat.com>
 
        * gimple.h (block_in_transaction): Move to basic-block.h and rename.
index 8cad9e1..9d19eb1 100644 (file)
@@ -1,3 +1,9 @@
+2013-11-06  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/58653
+       * gcc.dg/tree-ssa/predcom-6.c: New testcase.
+       * gcc.dg/tree-ssa/predcom-7.c: Likewise.
+
 2013-11-05  Balaji V. Iyer  <balaji.v.iyer@intel.com>
 
        * c-c++-common/cilk-plus/CK/fib.c: Reduced the iteration from
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/predcom-6.c b/gcc/testsuite/gcc.dg/tree-ssa/predcom-6.c
new file mode 100644 (file)
index 0000000..96d9bf9
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+
+int a, c, e[5][2]; 
+unsigned int d;
+
+int
+main ()
+{
+  for (d = 0; d < 2; d++)
+    if (a ? 0 : e[c + 3][d] & e[c + 4][d])
+      break;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/predcom-7.c b/gcc/testsuite/gcc.dg/tree-ssa/predcom-7.c
new file mode 100644 (file)
index 0000000..e7ae87c
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -fdump-tree-pcom-details" } */
+
+int b, f, d[5][2];
+unsigned int c;
+
+int
+main ()
+{
+  for (c = 0; c < 2; c++)
+    if (d[b + 3][c] & d[b + 4][c])
+      if (f)
+       break;
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump "Executing predictive commoning" "pcom" } } */
+/* { dg-final { cleanup-tree-dump "pcom" } } */
index 1005e78..3358f8b 100644 (file)
@@ -1334,90 +1334,29 @@ replace_ref_with (gimple stmt, tree new_tree, bool set, bool in_lhs)
   gsi_insert_after (&bsi, new_stmt, GSI_NEW_STMT);
 }
 
-/* Returns the reference to the address of REF in the ITER-th iteration of
-   LOOP, or NULL if we fail to determine it (ITER may be negative).  We
-   try to preserve the original shape of the reference (not rewrite it
-   as an indirect ref to the address), to make tree_could_trap_p in
-   prepare_initializers_chain return false more often.  */
-
-static tree
-ref_at_iteration (struct loop *loop, tree ref, int iter)
-{
-  tree idx, *idx_p, type, val, op0 = NULL_TREE, ret;
-  affine_iv iv;
-  bool ok;
-
-  if (handled_component_p (ref))
-    {
-      op0 = ref_at_iteration (loop, TREE_OPERAND (ref, 0), iter);
-      if (!op0)
-       return NULL_TREE;
-    }
-  else if (!INDIRECT_REF_P (ref)
-          && TREE_CODE (ref) != MEM_REF)
-    return unshare_expr (ref);
-
-  if (TREE_CODE (ref) == MEM_REF)
-    {
-      ret = unshare_expr (ref);
-      idx = TREE_OPERAND (ref, 0);
-      idx_p = &TREE_OPERAND (ret, 0);
-    }
-  else if (TREE_CODE (ref) == COMPONENT_REF)
-    {
-      /* Check that the offset is loop invariant.  */
-      if (TREE_OPERAND (ref, 2)
-         && !expr_invariant_in_loop_p (loop, TREE_OPERAND (ref, 2)))
-       return NULL_TREE;
-
-      return build3 (COMPONENT_REF, TREE_TYPE (ref), op0,
-                    unshare_expr (TREE_OPERAND (ref, 1)),
-                    unshare_expr (TREE_OPERAND (ref, 2)));
-    }
-  else if (TREE_CODE (ref) == ARRAY_REF)
-    {
-      /* Check that the lower bound and the step are loop invariant.  */
-      if (TREE_OPERAND (ref, 2)
-         && !expr_invariant_in_loop_p (loop, TREE_OPERAND (ref, 2)))
-       return NULL_TREE;
-      if (TREE_OPERAND (ref, 3)
-         && !expr_invariant_in_loop_p (loop, TREE_OPERAND (ref, 3)))
-       return NULL_TREE;
-
-      ret = build4 (ARRAY_REF, TREE_TYPE (ref), op0, NULL_TREE,
-                   unshare_expr (TREE_OPERAND (ref, 2)),
-                   unshare_expr (TREE_OPERAND (ref, 3)));
-      idx = TREE_OPERAND (ref, 1);
-      idx_p = &TREE_OPERAND (ret, 1);
-    }
-  else
-    return NULL_TREE;
-
-  ok = simple_iv (loop, loop, idx, &iv, true);
-  if (!ok)
-    return NULL_TREE;
-  iv.base = expand_simple_operations (iv.base);
-  if (integer_zerop (iv.step))
-    *idx_p = unshare_expr (iv.base);
+/* Returns a memory reference to DR in the ITER-th iteration of
+   the loop it was analyzed in.  Append init stmts to STMTS.  */
+
+static tree 
+ref_at_iteration (data_reference_p dr, int iter, gimple_seq *stmts)
+{
+  tree off = DR_OFFSET (dr);
+  tree coff = DR_INIT (dr);
+  if (iter == 0)
+    ;
+  else if (TREE_CODE (DR_STEP (dr)) == INTEGER_CST)
+    coff = size_binop (PLUS_EXPR, coff,
+                      size_binop (MULT_EXPR, DR_STEP (dr), ssize_int (iter)));
   else
-    {
-      type = TREE_TYPE (iv.base);
-      if (POINTER_TYPE_P (type))
-       {
-         val = fold_build2 (MULT_EXPR, sizetype, iv.step,
-                            size_int (iter));
-         val = fold_build_pointer_plus (iv.base, val);
-       }
-      else
-       {
-         val = fold_build2 (MULT_EXPR, type, iv.step,
-                            build_int_cst_type (type, iter));
-         val = fold_build2 (PLUS_EXPR, type, iv.base, val);
-       }
-      *idx_p = unshare_expr (val);
-    }
-
-  return ret;
+    off = size_binop (PLUS_EXPR, off,
+                     size_binop (MULT_EXPR, DR_STEP (dr), ssize_int (iter)));
+  tree addr = fold_build_pointer_plus (DR_BASE_ADDRESS (dr), off);
+  addr = force_gimple_operand_1 (addr, stmts, is_gimple_mem_ref_addr,
+                                NULL_TREE);
+  return fold_build2 (MEM_REF, TREE_TYPE (DR_REF (dr)),
+                     addr,
+                     fold_convert (reference_alias_ptr_type (DR_REF (dr)),
+                                   coff));
 }
 
 /* Get the initialization expression for the INDEX-th temporary variable
@@ -2376,14 +2315,10 @@ prepare_initializers_chain (struct loop *loop, chain_p chain)
       if (chain->inits[i] != NULL_TREE)
        continue;
 
-      init = ref_at_iteration (loop, DR_REF (dr), (int) i - n);
-      if (!init)
-       return false;
-
+      init = ref_at_iteration (dr, (int) i - n, &stmts);
       if (!chain->all_always_accessed && tree_could_trap_p (init))
        return false;
 
-      init = force_gimple_operand (init, &stmts, false, NULL_TREE);
       if (stmts)
        gsi_insert_seq_on_edge_immediate (entry, stmts);