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
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);
}
--
2.51.0