tree-optimization/117113 - ICE with unroll-and-jam

Message ID 20250204100025.36F883858433@sourceware.org
State New
Headers
Series tree-optimization/117113 - ICE with unroll-and-jam |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_build--master-arm fail Patch failed to apply

Commit Message

Richard Biener Feb. 4, 2025, 9:59 a.m. UTC
  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.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

	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.
---
 gcc/gimple-loop-jam.cc                  | 12 +++++++++++-
 gcc/testsuite/gcc.dg/torture/pr117113.c | 20 ++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr117113.c
  

Patch

diff --git a/gcc/gimple-loop-jam.cc b/gcc/gimple-loop-jam.cc
index 9a2eba02dd9..5e6c04a7d7f 100644
--- a/gcc/gimple-loop-jam.cc
+++ b/gcc/gimple-loop-jam.cc
@@ -279,13 +279,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
@@ -301,6 +305,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;
+}