The change in r14-2852-gf5fb9ff2396fd4 failed to update patch_loop_exit to compensate for rewriting of a NE/EQ_EXPR to a new code. Fixed with the following.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. PR tree-optimization/111233 PR tree-optimization/111652 PR tree-optimization/111727 PR tree-optimization/111838 PR tree-optimization/112113 * tree-ssa-loop-split.cc (patch_loop_exit): Get the new guard code instead of the old guard stmt. (split_loop): Adjust. * gcc.dg/torture/pr111233.c: New testcase. * gcc.dg/torture/pr111652.c: Likewise. * gcc.dg/torture/pr111727.c: Likewise. * gcc.dg/torture/pr111838.c: Likewise. * gcc.dg/torture/pr112113.c: Likewise. --- gcc/testsuite/gcc.dg/torture/pr111233.c | 19 +++++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr111652.c | 15 +++++++++++++++ gcc/testsuite/gcc.dg/torture/pr111727.c | 14 ++++++++++++++ gcc/testsuite/gcc.dg/torture/pr111838.c | 17 +++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr112113.c | 16 ++++++++++++++++ gcc/tree-ssa-loop-split.cc | 9 ++++----- 6 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr111233.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr111652.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr111727.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr111838.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr112113.c diff --git a/gcc/testsuite/gcc.dg/torture/pr111233.c b/gcc/testsuite/gcc.dg/torture/pr111233.c new file mode 100644 index 00000000000..30934033ae0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr111233.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fsplit-loops" } */ + +int a, c, f; +char b, g; +int *d = &c; +long e; +int main() +{ + for (; e != 25; e++) { + f = -17; + for (; f <= 0; f = f + 7) { + g = f ? 0 : b; + a = *d; + } + } + if (a != 0) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.dg/torture/pr111652.c b/gcc/testsuite/gcc.dg/torture/pr111652.c new file mode 100644 index 00000000000..ebca9c79816 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr111652.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fsplit-loops" } */ + +volatile int a; +int b; +int main() { + for (; b < 5; b += 3) { + b && a; + if (b < 4) + a--; + } + if (b != 6) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr111727.c b/gcc/testsuite/gcc.dg/torture/pr111727.c new file mode 100644 index 00000000000..fb68e197e2b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr111727.c @@ -0,0 +1,14 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fsplit-loops" } */ + +int a, b; +int main() +{ + for (; a < 4; a += 2) + if (a > 2) + while (b++); + ; + if (a != 4) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr111838.c b/gcc/testsuite/gcc.dg/torture/pr111838.c new file mode 100644 index 00000000000..67007d9742d --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr111838.c @@ -0,0 +1,17 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fsplit-loops" } */ + +int a, b, c; +volatile char d; +int main() +{ + for (; b < 1; b++) + for (char e = -17; e < 1; e += 5) + { + if (e ? a % e : 0) + d; + for (c = 0; c < 1; c++) + ; + } + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr112113.c b/gcc/testsuite/gcc.dg/torture/pr112113.c new file mode 100644 index 00000000000..96cd75f1be2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr112113.c @@ -0,0 +1,16 @@ +/* { dg-do run } */ +/* The -Waggressive-loop-optimizations diagnostic is spurious, missed + constant propagation after final value replacement. */ +/* { dg-additional-options "-Wno-aggressive-loop-optimizations -fsplit-loops" } */ + +volatile int a; +int main() +{ + for (int b = 0; b < 33; b += 3) { + if (b > 31) + a++; + } + if (a != 0) + __builtin_abort(); + return 0; +} diff --git a/gcc/tree-ssa-loop-split.cc b/gcc/tree-ssa-loop-split.cc index 64464802c1e..2e2adb67260 100644 --- a/gcc/tree-ssa-loop-split.cc +++ b/gcc/tree-ssa-loop-split.cc @@ -194,13 +194,12 @@ split_at_bb_p (class loop *loop, basic_block bb, tree *border, affine_iv *iv, also be true/false in the next iteration. */ static void -patch_loop_exit (class loop *loop, gcond *guard, tree nextval, tree newbound, - bool initial_true) +patch_loop_exit (class loop *loop, tree_code guard_code, tree nextval, + tree newbound, bool initial_true) { edge exit = single_exit (loop); gcond *stmt = as_a <gcond *> (*gsi_last_bb (exit->src)); - gimple_cond_set_condition (stmt, gimple_cond_code (guard), - nextval, newbound); + gimple_cond_set_condition (stmt, guard_code, nextval, newbound); update_stmt (stmt); edge stay = EDGE_SUCC (exit->src, EDGE_SUCC (exit->src, 0) == exit); @@ -745,7 +744,7 @@ split_loop (class loop *loop1) gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop1), stmts); tree guard_next = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop1)); - patch_loop_exit (loop1, guard_stmt, guard_next, newend, initial_true); + patch_loop_exit (loop1, guard_code, guard_next, newend, initial_true); /* Finally patch out the two copies of the condition to be always true/false (or opposite). */ -- 2.35.3