On Tue, 11 Aug 2026 at 20:16, Richard Henderson
<[email protected]> wrote:
>
> The trans_WHILE_ptr function incorrectly handles the case where the
> address difference divided by ESIZE results in zero. This happens when
> the address difference is less than ESIZE but greater than zero.
>
> Fix by dropping direct comparisons of op0 vs op1, and instead
> testing the scaled diff vs 0.  Merge with the bounding to the
> maximum vector length via wrapping arithmetic.
>
> Reported-by: YanjunYang <[email protected]>
> Signed-off-by: Richard Henderson <[email protected]>
> ---
>  target/arm/tcg/translate-sve.c | 38 +++++++++++++++++++++-------------
>  1 file changed, 24 insertions(+), 14 deletions(-)


> -    /* Since we're bounded, pass as a 32-bit type.  */
> +    /*
> +     * If diff == 0, the condition is always true.  Also, bound to max.
> +     * Simplify
> +     *    diff = diff ? diff : max;
> +     *    diff = umin(diff, max);
> +     * via
> +     *    diff -= 1;
> +     *    diff = umin(diff, max - 1);
> +     *    diff += 1;
> +     * via 0 - 1 == UINT64_MAX.
> +     */
> +    tcg_gen_addi_i64(diff, diff, -1);
> +    tcg_gen_umin_i64(diff, diff, tcg_constant_i64((vsz >> a->esz) - 1));
> +
> +    /*
> +     * Since we're bounded, pass as a 32-bit type.
> +     * Sink the diff += 1 from above into the 32-bit type.

Is it worth doing that? Hosts are all 64-bits now, and surely there's
not going to be a perf or codesize difference between "add 1"
on a 32-bit type vs a 64-bit type ?

> +     */
>      t2 = tcg_temp_new_i32();
>      tcg_gen_extrl_i64_i32(t2, diff);
> +    tcg_gen_addi_i32(t2, t2, 1);
>
>      desc = FIELD_DP32(desc, PREDDESC, OPRSZ, vsz / 8);
>      desc = FIELD_DP32(desc, PREDDESC, ESZ, a->esz);

-- PMM

Reply via email to