On Fri, 27 Feb 2026, Tamar Christina wrote:
> 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.
>
> Bootstrapped Regtested on aarch64-none-linux-gnu,
> arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
> -m32, -m64 and 1 test failure on -m32 that I'm
> looking at but seems unrelated/latent.
>
> This reduced example:
>
> long long a[1024];
> float b[1024];
> float c;
> void abort();
> int main() {
> int d;
> volatile float e;
> volatile double h, i, f, g = 1.0f;
> for (; c == e;)
> for (; (i = f) == g;)
> ;
> for (d = 0; d < 4; d++)
> if (d == 0)
> b[d] = h;
so at least b[0] is random (h is uninitialized), as a[] isn't written to
and neither the rest of b is I think this is just UB?
> for (d = 0; d < 1024; d++)
> if (a[d] != (__typeof(0))b[d])
> abort();
> }
>
> works with -fno-tree-vectorize, but is broken
> with -ftree-vectorize and we reject the loop
> during analysis. I've checked that just
> unconditionally returning opt_result::failure_at
> also triggers this so is unrelated to the patch.
>
> Something goes wrong during cleanup.
>
> Any objections? I won't commit till fixing the other
> bug.
OK.
Thanks,
Richard.
> Thanks,
> Tamar
>
> 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 --git a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s332.c
> b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s332.c
> index
> 21a9c5a6b2b6a81762977d6caaeaca06b67d29fb..04727388fc9c648981454c2fa4a38afa96b01126
> 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
> e4433385d6686806a75fffe22f90e3bfb603564c..24ac2fbedd2d64a6c98de922b058e4d5f7a93ef5
> 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
> 146df409ecc64e9535583c0d0083469d7aa24031..38426845a3d115432bfc68d9e1e7539fe10e27e2
> 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
> 0000000000000000000000000000000000000000..b9141e3f15a9d152118c2d8e84fc45d5e83066cb
> --- /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
> c789ec01f32c6b958c6a3663531a7b7517b94477..0cd20549cdc656baad2b5561e39ca999bca98bb0
> 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
> 8980b9f04f9a15ded9e90954e25b2c0578681761..b252b80ef291efd4f6fc98224a44ef7fadc68d6c
> 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
> 4977e425e81b23f4f449ae41ceb3f95f51bb7cb9..25eb2b07c600e3f2e0dec47182ab502a95fd3ddf
> 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
>
>
>
--
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)