2015-08-05 Richard Biener <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 Aug 2015 14:16:51 +0000 (14:16 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 Aug 2015 14:16:51 +0000 (14:16 +0000)
PR tree-optimization/67121
* tree-if-conv.c (combine_blocks): Clear range-info produced
by stmts no longer executed conditionally.

* gcc.dg/torture/pr67121.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@226630 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr67121.c [new file with mode: 0644]
gcc/tree-if-conv.c

index 7769097..bca92e2 100644 (file)
@@ -1,3 +1,9 @@
+2015-08-05  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/67121
+       * tree-if-conv.c (combine_blocks): Clear range-info produced
+       by stmts no longer executed conditionally.
+
 2015-08-05  Nick Clifton  <nickc@redhat.com>
 
        * config/rl78/rl78.c (rl78_force_nonfar_3): Remove optimization
index 62a4080..5ca71c9 100644 (file)
@@ -1,3 +1,8 @@
+2015-08-05  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/67121
+       * gcc.dg/torture/pr67121.c: New testcase.
+
 2015-08-05  Nick Clifton  <nickc@redhat.com>
 
        * gcc.target/rl78: New directory.
diff --git a/gcc/testsuite/gcc.dg/torture/pr67121.c b/gcc/testsuite/gcc.dg/torture/pr67121.c
new file mode 100644 (file)
index 0000000..2b609ee
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+int a[6], b, c = 226, d, e, f;
+signed char g;
+
+void
+fn1 (int p1)
+{
+  b = a[p1];
+}
+
+int
+main ()
+{
+  a[0] = 1;
+  for (f = 0; f < 9; f++)
+    {
+      signed char h = c;
+      int i = 1;
+      g = h < 0 ? h : h >> i;
+      e = g;
+      for (d = 1; d; d = 0)
+       ;
+    }
+  fn1 (g >> 8 & 1);
+
+  if (b != 0) 
+    __builtin_abort (); 
+
+  return 0;
+}
index b5de1b2..291e602 100644 (file)
@@ -2199,9 +2199,11 @@ combine_blocks (struct loop *loop, bool any_mask_load_store)
   /* Merge basic blocks: first remove all the edges in the loop,
      except for those from the exit block.  */
   exit_bb = NULL;
+  bool *predicated = XNEWVEC (bool, orig_loop_num_nodes);
   for (i = 0; i < orig_loop_num_nodes; i++)
     {
       bb = ifc_bbs[i];
+      predicated[i] = !is_true_predicate (bb_predicate (bb));
       free_bb_predicate (bb);
       if (bb_with_exit_edge_p (loop, bb))
        {
@@ -2259,9 +2261,21 @@ combine_blocks (struct loop *loop, bool any_mask_load_store)
       if (bb == exit_bb || bb == loop->latch)
        continue;
 
-      /* Make stmts member of loop->header.  */
+      /* Make stmts member of loop->header and clear range info from all stmts
+        in BB which is now no longer executed conditional on a predicate we
+        could have derived it from.  */
       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-       gimple_set_bb (gsi_stmt (gsi), merge_target_bb);
+       {
+         gimple stmt = gsi_stmt (gsi);
+         gimple_set_bb (stmt, merge_target_bb);
+         if (predicated[i])
+           {
+             ssa_op_iter i;
+             tree op;
+             FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF)
+               reset_flow_sensitive_info (op);
+           }
+       }
 
       /* Update stmt list.  */
       last = gsi_last_bb (merge_target_bb);
@@ -2281,6 +2295,7 @@ combine_blocks (struct loop *loop, bool any_mask_load_store)
 
   free (ifc_bbs);
   ifc_bbs = NULL;
+  free (predicated);
 }
 
 /* Version LOOP before if-converting it; the original loop