tree-optimization/111233 - loop splitting miscompile

Message ID 20231114141352.F3BC2385840E@sourceware.org
State Accepted
Headers
Series tree-optimization/111233 - loop splitting miscompile |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Richard Biener Nov. 14, 2023, 2:13 p.m. UTC
  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
  

Patch

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).  */