aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-11-14 14:26:17 +0100
committerRichard Biener <rguenther@suse.de>2023-11-14 15:10:16 +0100
commit2066c29bf8dea87c9810eb261e342d941a6b2059 (patch)
tree34492059041d5693822be11a08626a4192d03d7e /gcc
parentbc390ae72ff974d6985639b5b392f6e9192c2ee7 (diff)
downloadgcc-2066c29bf8dea87c9810eb261e342d941a6b2059.zip
gcc-2066c29bf8dea87c9810eb261e342d941a6b2059.tar.gz
gcc-2066c29bf8dea87c9810eb261e342d941a6b2059.tar.bz2
tree-optimization/111233 - loop splitting miscompile
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. 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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr111233.c19
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr111652.c15
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr111727.c14
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr111838.c17
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr112113.c16
-rw-r--r--gcc/tree-ssa-loop-split.cc9
6 files changed, 85 insertions, 5 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr111233.c b/gcc/testsuite/gcc.dg/torture/pr111233.c
new file mode 100644
index 0000000..3093403
--- /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 0000000..ebca9c7
--- /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 0000000..fb68e19
--- /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 0000000..67007d9
--- /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 0000000..96cd75f
--- /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 6446480..2e2adb6 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). */