LGTM :)
Jin Ma <[email protected]> 於 2026年8月19日週三 下午3:53寫道: > > When gimple-isel lowers a variable-index element access on a > fixed-length vector into .VEC_SET or .VEC_EXTRACT, the index may be > narrower than Pmode. The vec_set and vec_extract expanders used > gen_lowpart to convert it to Pmode, which only reinterprets the > register and drops the source-level truncation. The full 64-bit > value is then used as the slide amount of vslideup/vslidedown and > wrong code is generated. > > Fix this by zero-extending a sub-Pmode index with convert_to_mode > instead. > > PR target/126873 > > gcc/ChangeLog: > > * config/riscv/autovec.md (vec_set<mode>): Zero-extend a > sub-Pmode index to Pmode. > (vec_extract<mode><vel>): Likewise. > > gcc/testsuite/ChangeLog: > > * gcc.target/riscv/pr126873.c: New test. > > Signed-off-by: Jin Ma <[email protected]> > --- > gcc/config/riscv/autovec.md | 4 +-- > gcc/testsuite/gcc.target/riscv/pr126873.c | 37 +++++++++++++++++++++++ > 2 files changed, 39 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/riscv/pr126873.c > > diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md > index 964eed927c8..16d08cae30b 100644 > --- a/gcc/config/riscv/autovec.md > +++ b/gcc/config/riscv/autovec.md > @@ -1396,7 +1396,7 @@ (define_expand "vec_set<mode>" > > /* Here we set VL = offset + 1. */ > rtx length = gen_reg_rtx (Pmode); > - operands[2] = gen_lowpart (Pmode, operands[2]); > + operands[2] = convert_to_mode (Pmode, operands[2], true); > if (CONST_INT_P (operands[2])) > emit_move_insn (length, GEN_INT (INTVAL (operands[2]) + 1)); > else > @@ -1452,7 +1452,7 @@ (define_expand "vec_extract<mode><vel>" > > /* Emit the slide down to index 0 in a new vector. */ > tmp = gen_reg_rtx (<MODE>mode); > - operands[2] = gen_lowpart (Pmode, operands[2]); > + operands[2] = convert_to_mode (Pmode, operands[2], true); > rtx ops[] = {tmp, operands[1], operands[2]}; > riscv_vector::emit_vlmax_insn > (code_for_pred_slide (UNSPEC_VSLIDEDOWN, <MODE>mode), > diff --git a/gcc/testsuite/gcc.target/riscv/pr126873.c > b/gcc/testsuite/gcc.target/riscv/pr126873.c > new file mode 100644 > index 00000000000..eab525d0cf2 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/pr126873.c > @@ -0,0 +1,37 @@ > +/* { dg-do run { target rv64 } } */ > +/* { dg-require-effective-target riscv_v } */ > +/* { dg-require-effective-target rvv_zvl128b_ok } */ > +/* { dg-options "-march=rv64gcv -mabi=lp64d -O1" } */ > + > +typedef unsigned short u16 __attribute__ ((vector_size (4))); > + > +unsigned long long g; > + > +void __attribute__ ((noinline)) > +f1 (unsigned long long a3) > +{ > + unsigned long long v15 > + = __builtin_bswap64 ((long long) 10398105857157080808ull > + / (long long) a3); > + u16 bc13 = (u16) { 29637 }; > + if (0 >= bc13[(unsigned int) v15]) > + __builtin_abort (); > +} > + > +u16 __attribute__ ((noinline)) > +f2 (u16 in) > +{ > + in[(unsigned int) g] = 123; > + return in; > +} > + > +int > +main (void) > +{ > + f1 (17752357569705450221ull); > + g = 0x0b00000000000000ull; > + u16 r = f2 ((u16) { 1, 2 }); > + if (r[0] != 123 || r[1] != 2) > + __builtin_abort (); > + return 0; > +} > -- > 2.52.0 >
