From d7f3749967a0324564c644544ab00e2f7bfb84af Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 5 Aug 2015 14:16:51 +0000 Subject: [PATCH] re PR tree-optimization/67121 (wrong code at -O3 on x86_64-linux-gnu) 2015-08-05 Richard Biener 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. From-SVN: r226630 --- gcc/ChangeLog | 6 +++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/torture/pr67121.c | 31 ++++++++++++++++++++++++++ gcc/tree-if-conv.c | 19 ++++++++++++++-- 4 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr67121.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 77690973db3..bca92e28dc4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-08-05 Richard Biener + + 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 * config/rl78/rl78.c (rl78_force_nonfar_3): Remove optimization diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 62a4080d46b..5ca71c95c0d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-08-05 Richard Biener + + PR tree-optimization/67121 + * gcc.dg/torture/pr67121.c: New testcase. + 2015-08-05 Nick Clifton * 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 00000000000..2b609ee8316 --- /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 b5de1b2cdb6..291e6020b25 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 -- 2.30.2