https://gcc.gnu.org/g:09ea2b042881a6fad24e9b96029b62b93eda4fea

commit r17-1614-g09ea2b042881a6fad24e9b96029b62b93eda4fea
Author: Tamar Christina <[email protected]>
Date:   Wed Jun 17 12:09:22 2026 +0100

    vect: Fix early break in PEELED cases [PR125804]
    
    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.
    
    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.

Diff:
---
 .../gcc.dg/vect/vect-early-break_144-pr125804.c    | 51 ++++++++++++++++++++++
 gcc/tree-vect-loop-manip.cc                        |  3 +-
 2 files changed, 53 insertions(+), 1 deletion(-)

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 000000000000..f8974023ee6a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_144-pr125804.c
@@ -0,0 +1,51 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-do run } */
+/* { dg-require-effective-target vect_early_break_hw } */
+/* { dg-require-effective-target vect_long } */
+
+/* { dg-additional-options "-mavx512f" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-require-effective-target avx512f_runtime { target i?86-*-* x86_64-*-* 
} } */
+
+#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" { target { ! 
arm*-*-* } } } } */
+/* { dg-final { scan-tree-dump "early break does not require epilog" "vect" { 
target { ! arm*-*-* } } } } */
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index d2c854e16d44..a64a79d3299f 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);

Reply via email to