[llvm] ddf3f1b - [RISCV] Stop isInterleaveShuffle from producing illegal extract_subvectors.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 21 08:52:35 PDT 2023


Author: Craig Topper
Date: 2023-06-21T08:52:28-07:00
New Revision: ddf3f1b3b21c94a212a0d2e97a47c80cee833854

URL: https://github.com/llvm/llvm-project/commit/ddf3f1b3b21c94a212a0d2e97a47c80cee833854
DIFF: https://github.com/llvm/llvm-project/commit/ddf3f1b3b21c94a212a0d2e97a47c80cee833854.diff

LOG: [RISCV] Stop isInterleaveShuffle from producing illegal extract_subvectors.

The definition for ISD::EXTRACT_SUBVECTOR says the index must be
aligned to the known minimum elements of the extracted type. We mostly
got away with this but it turns out there are places that depend on this.

For example, this code in getNode for ISD::EXTRACT_SUBVECTOR

```
    // EXTRACT_SUBVECTOR of CONCAT_VECTOR can be simplified if the pieces of
    // the concat have the same type as the extract.
    if (N1.getOpcode() == ISD::CONCAT_VECTORS && N1.getNumOperands() > 0 &&
        VT == N1.getOperand(0).getValueType()) {
      unsigned Factor = VT.getVectorMinNumElements();
      return N1.getOperand(N2C->getZExtValue() / Factor);
    }
```

This depends on N2C->getZExtValue() being evenly divisible by Factor.

Reviewed By: luke

Differential Revision: https://reviews.llvm.org/D153380

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVISelLowering.cpp
    llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int-interleave.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 040fb6836cf90..f68b49d6d3d25 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -3520,10 +3520,11 @@ static bool isInterleaveShuffle(ArrayRef<int> Mask, MVT VT, int &EvenSrc,
   // 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
index 9da8726ff9993..7d7aa9c3b5493 100644
--- 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_2(<4 x i32> %x, <4 x i32> %y) {
 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> <i32 0, i32 5, i32 1, i32 6>
   ret <4 x i32> %a
@@ -762,22 +767,19 @@ define <8 x i32> @unary_interleave_v8i32(<8 x i32> %x) {
 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> <i32 1, i32 0, i32 undef, i32 undef>


        


More information about the llvm-commits mailing list