Re: [PATCH v2 2/3] target/arm: Fix SVE2 WHILEWR/WHILERW zero diff boundary case
Peter Maydell <[email protected]>
| Newsgroups | org.nongnu.qemu-arm,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <CAFEAcA98oxLs-w1PNuoM9mArit=toTCTucD5xOmN29Rbk6XBTQ@mail.gmail.com> |
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