diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -3520,10 +3520,11 @@ // vectors, or at the start and middle of the first vector if it's an unary // interleave. // In both cases, HalfNumElts will be extracted. - // So make sure that EvenSrc/OddSrc are within range. + // We need to ensure that the extract indices are 0 or HalfNumElts otherwise + // we'll create an illegal extract_subvector. + // FIXME: We could support other values using a slidedown first. int HalfNumElts = NumElts / 2; - return (((EvenSrc % NumElts) + HalfNumElts) <= NumElts) && - (((OddSrc % NumElts) + HalfNumElts) <= NumElts); + return ((EvenSrc % HalfNumElts) == 0) && ((OddSrc % HalfNumElts) == 0); } /// Match shuffles that concatenate two vectors, rotate the concatenation, diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int-interleave.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int-interleave.ll --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int-interleave.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int-interleave.ll @@ -202,23 +202,28 @@ define <4 x i32> @interleave_v4i32_offset_1(<4 x i32> %x, <4 x i32> %y) { ; V128-LABEL: interleave_v4i32_offset_1: ; V128: # %bb.0: -; V128-NEXT: vsetivli zero, 2, e32, m1, ta, ma -; V128-NEXT: vslidedown.vi v10, v9, 1 -; V128-NEXT: vsetivli zero, 2, e32, mf2, ta, ma -; V128-NEXT: vwaddu.vv v9, v8, v10 -; V128-NEXT: li a0, -1 -; V128-NEXT: vwmaccu.vx v9, a0, v10 -; V128-NEXT: vmv1r.v v8, v9 +; V128-NEXT: vsetivli zero, 4, e32, m1, ta, mu +; V128-NEXT: vid.v v10 +; V128-NEXT: vsrl.vi v11, v10, 1 +; V128-NEXT: vrgather.vv v10, v8, v11 +; V128-NEXT: li a0, 10 +; V128-NEXT: vmv.s.x v0, a0 +; V128-NEXT: vadd.vi v8, v11, 1 +; V128-NEXT: vrgather.vv v10, v9, v8, v0.t +; V128-NEXT: vmv.v.v v8, v10 ; V128-NEXT: ret ; ; V512-LABEL: interleave_v4i32_offset_1: ; V512: # %bb.0: -; V512-NEXT: vsetivli zero, 2, e32, mf2, ta, ma -; V512-NEXT: vslidedown.vi v10, v9, 1 -; V512-NEXT: vwaddu.vv v9, v8, v10 -; V512-NEXT: li a0, -1 -; V512-NEXT: vwmaccu.vx v9, a0, v10 -; V512-NEXT: vmv1r.v v8, v9 +; V512-NEXT: vsetivli zero, 4, e32, mf2, ta, mu +; V512-NEXT: vid.v v10 +; V512-NEXT: vsrl.vi v11, v10, 1 +; V512-NEXT: vrgather.vv v10, v8, v11 +; V512-NEXT: li a0, 10 +; V512-NEXT: vmv.s.x v0, a0 +; V512-NEXT: vadd.vi v8, v11, 1 +; V512-NEXT: vrgather.vv v10, v9, v8, v0.t +; V512-NEXT: vmv1r.v v8, v10 ; V512-NEXT: ret %a = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> ret <4 x i32> %a @@ -762,22 +767,19 @@ define <4 x i8> @unary_interleave_10uu_v4i8(<4 x i8> %x) { ; V128-LABEL: unary_interleave_10uu_v4i8: ; V128: # %bb.0: -; V128-NEXT: vsetivli zero, 2, e8, mf4, ta, ma -; V128-NEXT: vslidedown.vi v10, v8, 1 -; V128-NEXT: vsetivli zero, 2, e8, mf8, ta, ma -; V128-NEXT: vwaddu.vv v9, v10, v8 -; V128-NEXT: li a0, -1 -; V128-NEXT: vwmaccu.vx v9, a0, v8 +; V128-NEXT: vsetivli zero, 4, e8, mf4, ta, ma +; V128-NEXT: vid.v v9 +; V128-NEXT: vrsub.vi v10, v9, 1 +; V128-NEXT: vrgather.vv v9, v8, v10 ; V128-NEXT: vmv1r.v v8, v9 ; V128-NEXT: ret ; ; V512-LABEL: unary_interleave_10uu_v4i8: ; V512: # %bb.0: -; V512-NEXT: vsetivli zero, 2, e8, mf8, ta, ma -; V512-NEXT: vslidedown.vi v10, v8, 1 -; V512-NEXT: vwaddu.vv v9, v10, v8 -; V512-NEXT: li a0, -1 -; V512-NEXT: vwmaccu.vx v9, a0, v8 +; V512-NEXT: vsetivli zero, 4, e8, mf8, ta, ma +; V512-NEXT: vid.v v9 +; V512-NEXT: vrsub.vi v10, v9, 1 +; V512-NEXT: vrgather.vv v9, v8, v10 ; V512-NEXT: vmv1r.v v8, v9 ; V512-NEXT: ret %a = shufflevector <4 x i8> %x, <4 x i8> poison, <4 x i32>