summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2025-02-03 15:12:52 +0100
committerRichard Biener <rguenth@gcc.gnu.org>2025-06-24 13:07:50 +0200
commitf4dbdeabb2944d014d506a537a576a6f9a1f4c1f (patch)
treea866c8ba1587dceea37f1c00b9a1918bc4c81dc5
parent415bad120d8f21cd754d827da9e3d5e1fbe68d4c (diff)
tree-optimization/117113 - ICE with unroll-and-jam
When there's an inner loop without virtual header PHI but the outer loop has one the fusion process cannot handle the need to create an inner loop virtual header PHI. Punt in this case. PR tree-optimization/117113 * gimple-loop-jam.cc (unroll_jam_possible_p): Detect when we cannot handle virtual SSA update. * gcc.dg/torture/pr117113.c: New testcase. (cherry picked from commit 0675eb17480bada678bf2769d39732027abcd6d0)
-rw-r--r--gcc/gimple-loop-jam.cc12
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr117113.c20
2 files changed, 31 insertions, 1 deletions
diff --git a/gcc/gimple-loop-jam.cc b/gcc/gimple-loop-jam.cc
index e33dd9091df..22d518d9fb0 100644
--- a/gcc/gimple-loop-jam.cc
+++ b/gcc/gimple-loop-jam.cc
@@ -278,13 +278,17 @@ unroll_jam_possible_p (class loop *outer, class loop *loop)
body would be the after-iter value of the first body) if it's over
an associative and commutative operation. We wouldn't
be able to handle unknown cycles. */
+ bool inner_vdef = false;
for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi))
{
affine_iv iv;
tree op = gimple_phi_result (psi.phi ());
if (virtual_operand_p (op))
- continue;
+ {
+ inner_vdef = true;
+ continue;
+ }
if (!simple_iv (loop, loop, op, &iv, true))
return false;
/* The inductions must be regular, loop invariant step and initial
@@ -300,6 +304,12 @@ unroll_jam_possible_p (class loop *outer, class loop *loop)
copy, _not_ the next value of the second body. */
}
+ /* When there's no inner loop virtual PHI IV we cannot handle the update
+ required to the inner loop if that doesn't already have one. See
+ PR117113. */
+ if (!inner_vdef && get_virtual_phi (outer->header))
+ return false;
+
return true;
}
diff --git a/gcc/testsuite/gcc.dg/torture/pr117113.c b/gcc/testsuite/gcc.dg/torture/pr117113.c
new file mode 100644
index 00000000000..e90ad034a4d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr117113.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fno-tree-dce -fno-inline" } */
+
+int a, b, c;
+volatile int d[1];
+void e() {}
+void f(int g) {}
+int main() {
+ int i;
+ for (; b; b--) {
+ for (i = 0; i < 3; i++) {
+ e();
+ f(d[0]);
+ d[0];
+ }
+ if (a)
+ c++;
+ }
+ return 0;
+}