diff --git a/gcc/testsuite/gcc.dg/torture/pr114551.c b/gcc/testsuite/gcc.dg/torture/pr114551.c new file mode 100644 index 00000000000..13c15fbc3d9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr114551.c @@ -0,0 +1,18 @@ +/* { dg-do run } */ + +int a, b[4], c, d, e, f; +int main() +{ + a--; + for (f = 3; f >= 0; f--) + { + for (e = 0; e < 4; e++) + c = 0; + for (; c < 4; c++) + { + d = f && a > 0 && f > (2147483647 - a) ? 0 : b[f]; + continue; + } + } + return 0; +} diff --git a/gcc/tree-ssa-loop-split.cc b/gcc/tree-ssa-loop-split.cc index c0bb1b71d17..a770ea371a2 100644 --- a/gcc/tree-ssa-loop-split.cc +++ b/gcc/tree-ssa-loop-split.cc @@ -653,8 +653,26 @@ split_loop (class loop *loop1) gimple_seq stmts2; border = force_gimple_operand (border, &stmts2, true, NULL_TREE); if (stmts2) - gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop1), - stmts2); + { + /* When the split condition is not always evaluated make sure + to rewrite it to defined overflow. */ + if (!dominated_by_p (CDI_DOMINATORS, exit1->src, bbs[i])) + { + gimple_stmt_iterator gsi; + gsi = gsi_start (stmts2); + while (!gsi_end_p (gsi)) + { + gimple *stmt = gsi_stmt (gsi); + if (is_gimple_assign (stmt) + && arith_code_with_undefined_signed_overflow + (gimple_assign_rhs_code (stmt))) + rewrite_to_defined_overflow (&gsi); + gsi_next (&gsi); + } + } + gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop1), + stmts2); + } tree cond = fold_build2 (guard_code, boolean_type_node, guard_init, border); if (!initial_true)