> 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;
> +}
> 

Reply via email to