https://gcc.gnu.org/g:0383e6c398a0636c54209ce5822fd4fd43e9a99f

commit r16-7762-g0383e6c398a0636c54209ce5822fd4fd43e9a99f
Author: Tamar Christina <[email protected]>
Date:   Fri Feb 27 14:21:36 2026 +0000

    vect: enforce trapping math checks when early breaks [PR124142]
    
    The loop
    
    void
    __attribute__((noipa))
    bug (int f, int *w, int l)
    {
      int i;
      for (i = 0; i < l; ++i)
        while (f % w[i]) w[i]--;
    }
    
    is an uncounted loop which performs a trapping operation during 
vectorization.
    Normally the vectorizer doesn't stop vectorization if the operation can't be
    masked (though ifcvt does).
    
    For Early breaks however this is unsafe as we are introducing a trap where 
the
    original scalar code may not have.
    
    Some tests now fail to vectorize (including some tsvc ones) which I could 
have
    xfail'ed but instead decided to add -fno-trapping-math just to get the
    additional coverage they provide.
    
    gcc/ChangeLog:
    
            PR tree-optimization/124142
            * tree-vect-data-refs.cc (vect_analyze_early_break_dependences):
            For early break require masking when operation can trap.
    
    gcc/testsuite/ChangeLog:
    
            PR tree-optimization/124142
            * gcc.dg/vect/tsvc/vect-tsvc-s481.c: Add -fno-trapping-math.
            * gcc.dg/vect/tsvc/vect-tsvc-s332.c: Likewise.
            * gcc.dg/vect/tsvc/vect-tsvc-s482.c: Likewise.
            * gcc.dg/vect/vect-early-break_61.c: Likewise.
            * gcc.target/aarch64/vect-early-break-cbranch_3.c: Likewise.
            * gcc.dg/vect/vect-early-break_143-pr124142.c: New test

Diff:
---
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s332.c    |  2 +-
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s481.c    |  2 +-
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s482.c    |  2 +-
 .../gcc.dg/vect/vect-early-break_143-pr124142.c    | 16 +++++++++
 gcc/testsuite/gcc.dg/vect/vect-early-break_61.c    |  1 +
 .../aarch64/vect-early-break-cbranch_3.c           |  2 +-
 gcc/tree-vect-data-refs.cc                         | 38 ++++++++++++++++++++--
 7 files changed, 57 insertions(+), 6 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s332.c 
b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s332.c
index 21a9c5a6b2b6..04727388fc9c 100644
--- a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s332.c
+++ b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s332.c
@@ -1,7 +1,7 @@
 /*  This file is distributed under the University of Illinois Open Source
     License. See license.txt for details.  */
 
-/* { dg-additional-options "--param vect-epilogues-nomask=0" } */
+/* { dg-additional-options "--param vect-epilogues-nomask=0 
-fno-trapping-math" } */
 /* { dg-require-effective-target vect_float } */
 /* { dg-require-effective-target vect_early_break_hw } */
 /* { dg-add-options vect_early_break } */
diff --git a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s481.c 
b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s481.c
index e4433385d668..24ac2fbedd2d 100644
--- a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s481.c
+++ b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s481.c
@@ -1,7 +1,7 @@
 /*  This file is distributed under the University of Illinois Open Source
     License. See license.txt for details.  */
 
-/* { dg-additional-options "--param vect-epilogues-nomask=0" } */
+/* { dg-additional-options "--param vect-epilogues-nomask=0 
-fno-trapping-math" } */
 /* { dg-require-effective-target vect_float } */
 /* { dg-require-effective-target vect_early_break_hw } */
 /* { dg-add-options vect_early_break } */
diff --git a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s482.c 
b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s482.c
index 146df409ecc6..38426845a3d1 100644
--- a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s482.c
+++ b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s482.c
@@ -1,7 +1,7 @@
 /*  This file is distributed under the University of Illinois Open Source
     License. See license.txt for details.  */
 
-/* { dg-additional-options "--param vect-epilogues-nomask=0" } */
+/* { dg-additional-options "--param vect-epilogues-nomask=0 
-fno-trapping-math" } */
 /* { dg-require-effective-target vect_float } */
 /* { dg-require-effective-target vect_early_break_hw } */
 /* { dg-add-options vect_early_break } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_143-pr124142.c 
b/gcc/testsuite/gcc.dg/vect/vect-early-break_143-pr124142.c
new file mode 100644
index 000000000000..b9141e3f15a9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_143-pr124142.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+
+/* { dg-final { scan-tree-dump-not "LOOP VECTORIZED" "vect" } } */
+
+void
+__attribute__((noipa))
+bug (int f, int *w, int l)
+{
+  int i;
+  for (i = 0; i < l; ++i)
+    while (f % w[i]) w[i]--;
+}
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_61.c 
b/gcc/testsuite/gcc.dg/vect/vect-early-break_61.c
index c789ec01f32c..0cd20549cdc6 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-early-break_61.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_61.c
@@ -2,6 +2,7 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target vect_early_break } */
 /* { dg-require-effective-target vect_float } */
+/* { dg-additional-options "-fno-trapping-math" } */
 
 typedef float real_t;
 __attribute__((aligned(64))) real_t a[32000], b[32000], c[32000];
diff --git a/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_3.c 
b/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_3.c
index 8980b9f04f9a..b252b80ef291 100644
--- a/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_3.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O3 -fno-schedule-insns -fno-reorder-blocks 
-fno-schedule-insns2 --param aarch64-autovec-preference=asimd-only" } */
+/* { dg-options "-O3 -fno-trapping-math -fno-schedule-insns 
-fno-reorder-blocks -fno-schedule-insns2 --param 
aarch64-autovec-preference=asimd-only" } */
 /* { dg-final { check-function-bodies "**" "" "" { target lp64 } } } */
 
 #pragma GCC target "+sve"
diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc
index 4977e425e81b..25eb2b07c600 100644
--- a/gcc/tree-vect-data-refs.cc
+++ b/gcc/tree-vect-data-refs.cc
@@ -732,11 +732,45 @@ vect_analyze_early_break_dependences (loop_vec_info 
loop_vinfo)
          if (is_gimple_debug (stmt))
            continue;
 
+         stmt_vec_info orig_stmt_vinfo = loop_vinfo->lookup_stmt (stmt);
          stmt_vec_info stmt_vinfo
-           = vect_stmt_to_vectorize (loop_vinfo->lookup_stmt (stmt));
+           = vect_stmt_to_vectorize (orig_stmt_vinfo);
          auto dr_ref = STMT_VINFO_DATA_REF (stmt_vinfo);
          if (!dr_ref)
-           continue;
+           {
+             /* Trapping statements after the last early exit are fine.  */
+             if (check_deps)
+               {
+                 bool could_trap_p = false;
+                 gimple *cur_stmt = STMT_VINFO_STMT (stmt_vinfo);
+                 could_trap_p = gimple_could_trap_p (cur_stmt);
+                 if (STMT_VINFO_IN_PATTERN_P (orig_stmt_vinfo))
+                   {
+                     gimple_stmt_iterator gsi2;
+                     auto stmt_seq
+                       = STMT_VINFO_PATTERN_DEF_SEQ (orig_stmt_vinfo);
+                     for (gsi2 = gsi_start (stmt_seq);
+                          !could_trap_p && !gsi_end_p (gsi2); gsi_next (&gsi2))
+                       {
+                         cur_stmt = gsi_stmt (gsi2);
+                         could_trap_p = gimple_could_trap_p (cur_stmt);
+                       }
+                   }
+
+                 if (could_trap_p)
+                   {
+                     if (dump_enabled_p ())
+                       dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                            "cannot vectorize as operation may trap.\n");
+                     return opt_result::failure_at (cur_stmt,
+                            "can't safely apply code motion to dependencies"
+                            " to vectorize the early exit. %G may trap.\n",
+                            cur_stmt);
+                   }
+               }
+
+             continue;
+           }
 
          /* We know everything below dest_bb is safe since we know we
             had a full vector iteration when reaching it.  Either by

Reply via email to