tree-optimization/125477 - verify we can copy it before versioning an outer loop

Message ID 20260603065317.DDC1C4BA2E39@sourceware.org
State Committed
Headers
Series tree-optimization/125477 - verify we can copy it before versioning an outer loop |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm fail Patch failed to apply

Commit Message

Richard Biener June 3, 2026, 6:52 a.m. UTC
  The following fixes a hole in vectorizer loop versioning which tries to
version an outer loop that the versioning condition is invariant in but
fails to verify we can actually copy it.

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

	PR tree-optimization/125477
	* tree-vect-loop-manip.cc (vect_loop_versioning): Verify we
	can duplicate an outer loop before considering to version it.

	* gcc.dg/torture/pr125477.c: New testcase.
---
 gcc/testsuite/gcc.dg/torture/pr125477.c | 17 +++++++++++++++++
 gcc/tree-vect-loop-manip.cc             |  3 ++-
 2 files changed, 19 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr125477.c
  

Patch

diff --git a/gcc/testsuite/gcc.dg/torture/pr125477.c b/gcc/testsuite/gcc.dg/torture/pr125477.c
new file mode 100644
index 00000000000..683c204ecbd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr125477.c
@@ -0,0 +1,17 @@ 
+/* { dg-do compile } */
+
+void f123(void) __attribute__((__returns_twice__));
+int c;
+volatile int i;
+void e(long *a, long *d, int f) {
+g:
+  if (i)
+    return;
+  f123();
+  for (;;) {
+    __asm__ goto("" : : : : g);
+    c = 0;
+    for (; c < f; c++)
+      a[c] = d[c];
+  }
+}
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index a6d58d6798c..5ce961a1bb0 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -4494,7 +4494,8 @@  vect_loop_versioning (loop_vec_info loop_vinfo,
 	     && (!loop_outer (loop_to_version)->inner->next
 		 || vect_loop_vectorized_call (loop_to_version))
 	     && (!loop_outer (loop_to_version)->inner->next
-		 || !loop_outer (loop_to_version)->inner->next->next))
+		 || !loop_outer (loop_to_version)->inner->next->next)
+	     && can_duplicate_loop_p (loop_outer (loop_to_version)))
 	loop_to_version = loop_outer (loop_to_version);
     }