When a loop is LOOP_VINFO_EARLY_BREAKS_VECT_PEELED && ! LOOP_VINFO_EARLY_BRK_NEEDS_EPILOG then we still need the epilog loop for the main latch edge.
The early exits themselves when LOOP_VINFO_EARLY_BRK_NEEDS_EPILOG don't need to
go to scalar code.
Allowing bound_epilog to still be set to VF when
LOOP_VINFO_EARLY_BREAKS_VECT_PEELED we get to the desired effect that the early
exits do not require an epilog when !LOOP_VINFO_EARLY_BRK_NEEDS_EPILOG but
the main edge still does if LOOP_VINFO_EARLY_BREAKS_VECT_PEELED.
Bootstrapped Regtested on aarch64-none-linux-gnu,
arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
-m32, -m64 and no issues.
Pushed to master.
Thanks,
Tamar
gcc/ChangeLog:
PR tree-optimization/125804
* tree-vect-loop-manip.cc (vect_do_peeling): Have
LOOP_VINFO_EARLY_BREAKS_VECT_PEELED require epilog.
gcc/testsuite/ChangeLog:
PR tree-optimization/125804
* gcc.dg/vect/vect-early-break_144-pr125804.c: New test.
-- inline copy of patch --
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_144-pr125804.c
b/gcc/testsuite/gcc.dg/vect/vect-early-break_144-pr125804.c
new file mode 100644
index
0000000000000000000000000000000000000000..7afca96e304928042291b56546d7b8a80764dbf4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_144-pr125804.c
@@ -0,0 +1,48 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_long } */
+
+#include "tree-vect.h"
+
+typedef struct {
+ unsigned b;
+ long long bits[2];
+} c;
+typedef struct {
+ c *d;
+} e, *bitmap;
+e f;
+int g;
+
+__attribute__((noipa))
+int h(bitmap i) {
+ c j = *i->d;
+ unsigned k, l = j.b < 4;
+ for (; l < 2; l++) {
+ long long m = j.bits[l];
+ for (; k < 64; k++) {
+ long long n = (long long)1LL << k;
+ if (m & n)
+ goto o;
+ }
+ k = 0;
+ }
+ return 0;
+o:
+ return 1;
+}
+
+int main() {
+
+ check_vect ();
+
+ c a;
+ a.bits[0] = 1ull << 63;
+ f.d = &a;
+ g = h(&f);
+ return g == 0;
+}
+
+/* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 1 "vect" } } */
+/* { dg-final { scan-tree-dump "early break does not require epilog" "vect" }
} */
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index
d2c854e16d4413dc26ab1ec35d20633ef415d01c..a64a79d3299fb65d46c68a438448b7bcd5da0846
100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -3320,7 +3320,8 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters,
tree nitersm1,
/* For early breaks the scalar loop needs to execute at most VF times
to find the element that caused the break. */
if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo)
- && LOOP_VINFO_EARLY_BRK_NEEDS_EPILOG (loop_vinfo))
+ && (LOOP_VINFO_EARLY_BRK_NEEDS_EPILOG (loop_vinfo)
+ || LOOP_VINFO_EARLY_BREAKS_VECT_PEELED (loop_vinfo)))
bound_epilog = vf;
bool epilog_peeling = maybe_ne (bound_epilog, 0U);
rb20616.patch
Description: rb20616.patch
