Similar to if-combine if-conversion invalidates range info on stmts that are executed unconditionally only after the transform. Thus we have to invalidate it.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2015-08-05 Richard Biener <rguent...@suse.de> 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. Index: gcc/tree-if-conv.c =================================================================== --- gcc/tree-if-conv.c (revision 226612) +++ gcc/tree-if-conv.c (working copy) @@ -2199,9 +2199,11 @@ combine_blocks (struct loop *loop, bool /* 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 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 free (ifc_bbs); ifc_bbs = NULL; + free (predicated); } /* Version LOOP before if-converting it; the original loop Index: gcc/testsuite/gcc.dg/torture/pr67121.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr67121.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr67121.c (working copy) @@ -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; +}