aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr67121.c31
-rw-r--r--gcc/tree-if-conv.c19
4 files changed, 59 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7769097..bca92e2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 62a4080..5ca71c9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..2b609ee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr67121.c
@@ -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;
+}
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index b5de1b2..291e602 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -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