> On 12 Nov 2026, at 12:34, Tamar Christina <[email protected]> wrote:
>
> The following testcase
>
> const double a[] = {0, 1, 2, 3, 4, 5};
> __attribute__((noipa))
> int f(double x)
> {
> int i = 0;
> #pragma GCC unroll 0
> while (i < 6 && a[i] <= x)
> ++i;
> return i;
> }
> int main(void)
> {
> int result = f(2.0);
> return result != 3;
> }
>
> when compiled with -O3 -fno-trapping-math -march=armv8-a+sve
>
> generates incorrect code:
>
> f:
> ptrue p15.b, vl16
> ptrue p7.b, all
> dup v30.2d, v0.d[0]
> adrp x2, .LANCHOR0
> add x1, x2, :lo12:.LANCHOR0
> mov w0, 0
> .L5:
> ldr q31, [x1]
> add x1, x1, 16
> fcmle p14.d, p7/z, z31.d, z30.d
> bics p14.b, p15/z, p7.b, p14.b
> b.any .L10
> add w0, w0, 2
> cmp w0, 6
> bne .L5
> ret
>
> with this patch the mask is corrected to
>
> f:
> ptrue p15.d, vl2
> ptrue p7.b, all
> dup v30.2d, v0.d[0]
> adrp x2, .LANCHOR0
> add x1, x2, :lo12:.LANCHOR0
> mov w0, 0
> .L5:
> ldr q31, [x1]
> add x1, x1, 16
> fcmle p14.d, p7/z, z31.d, z30.d
> bics p14.b, p15/z, p7.b, p14.b
> b.any .L10
> add w0, w0, 2
> cmp w0, 6
> bne .L5
> ret
>
> Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
>
> Ok for master? and GCC-16?
>
Ok.
Thanks,
Kyrill
> Thanks,
> Tamar
>
> gcc/ChangeLog:
>
> PR target/128665
> * config/aarch64/aarch64-simd.md (vec_cbranch_any,
> vec_cbranch_all): Correct mask.
>
> gcc/testsuite/ChangeLog:
>
> PR target/128665
> * gcc.target/aarch64/sve/vect-revectorize-ptest-1.c: New test.
>
> ---
>
> --
> diff --git a/gcc/config/aarch64/aarch64-simd.md
> b/gcc/config/aarch64/aarch64-simd.md
> index
> 11705bc9073801dbc1a25ce3d9723ba9a96c446f..9c054090defab1b461f684eb4ddf234f1e40fe21
> 100644
> --- a/gcc/config/aarch64/aarch64-simd.md
> +++ b/gcc/config/aarch64/aarch64-simd.md
> @@ -4585,6 +4585,16 @@ (define_expand "<optab><mode>"
> = exact_div (GET_MODE_BITSIZE (<MODE>mode), 8).to_constant ();
> machine_mode pred_mode = aarch64_sve_pred_mode (full_mode);
> rtx ptrue = aarch64_ptrue_reg (VNx16BImode, lanes);
> + /* The predicate created above limits the VL but does not encapsulate
> + the element width from the original mode. However the interface to
> + aarch64_ptrue_reg doesn't allow this so we have to create 1 predicate
> + for the length and one for the shape, and AND them together. Constant
> + folding takes care of the rest. This is easier than manually encoding
> + the bits. */
> + rtx mask
> + = force_reg (VNx16BImode,
> + aarch64_ptrue_all (GET_MODE_UNIT_SIZE (<MODE>mode)));
> + emit_insn (gen_and3 (VNx16BImode, ptrue, ptrue, mask));
> rtx hint = gen_int_mode (SVE_MAYBE_NOT_PTRUE, SImode);
>
> rtx tmp = gen_reg_rtx (pred_mode);
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-revectorize-ptest-1.c
> b/gcc/testsuite/gcc.target/aarch64/sve/vect-revectorize-ptest-1.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..777e4d3fc00aec45e1f6019476853f367adcba03
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-revectorize-ptest-1.c
> @@ -0,0 +1,23 @@
> +/* { dg-do run { target aarch64_sve_hw } } */
> +/* { dg-options "-O3 -fno-trapping-math -march=armv8-a+sve" } */
> +
> +/* PTEST must ignore the predicate bits between 64-bit elements. */
> +
> +const double a[] = { 0, 1, 2, 3, 4, 5 };
> +
> +__attribute__((noipa))
> +int
> +f (double x)
> +{
> + int i = 0;
> +#pragma GCC unroll 0
> + while (i < 6 && a[i] <= x)
> + ++i;
> + return i;
> +}
> +
> +int
> +main (void)
> +{
> + return f (2.0) != 3;
> +}
>