[llvm] [RISCV] Fix incorrect lowering of VECTOR_INTERLEAVE on fixed vectors (PR #212642)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 30 01:40:01 PDT 2026


================
@@ -13931,25 +13894,45 @@ SDValue RISCVTargetLowering::lowerVECTOR_INTERLEAVE(SDValue Op,
         Intrinsic::riscv_vsseg6_mask, Intrinsic::riscv_vsseg7_mask,
         Intrinsic::riscv_vsseg8_mask,
     };
+    static const Intrinsic::ID FixedIntrIds[] = {
+        Intrinsic::riscv_seg2_store_mask, Intrinsic::riscv_seg3_store_mask,
+        Intrinsic::riscv_seg4_store_mask, Intrinsic::riscv_seg5_store_mask,
+        Intrinsic::riscv_seg6_store_mask, Intrinsic::riscv_seg7_store_mask,
+        Intrinsic::riscv_seg8_store_mask,
+    };
 
-    unsigned Sz =
-        Factor * VecVT.getVectorMinNumElements() * VecVT.getScalarSizeInBits();
-    EVT VecTupTy = MVT::getRISCVVectorTupleVT(Sz, Factor);
-
-    SDValue StoredVal = DAG.getUNDEF(VecTupTy);
-    for (unsigned i = 0; i < Factor; i++)
-      StoredVal =
-          DAG.getNode(RISCVISD::TUPLE_INSERT, DL, VecTupTy, StoredVal,
-                      Op.getOperand(i), DAG.getTargetConstant(i, DL, MVT::i32));
-
-    SDValue Ops[] = {DAG.getEntryNode(),
-                     DAG.getTargetConstant(IntrIds[Factor - 2], DL, XLenVT),
-                     StoredVal,
-                     StackPtr,
-                     Mask,
-                     VL,
-                     DAG.getTargetConstant(Log2_64(VecVT.getScalarSizeInBits()),
-                                           DL, XLenVT)};
+    SmallVector<SDValue> Ops;
+    if (VecVT.isFixedLengthVector()) {
+      Ops = {DAG.getEntryNode(),
+             DAG.getTargetConstant(FixedIntrIds[Factor - 2], DL, XLenVT)};
+      for (unsigned i = 0U; i < Factor; ++i)
+        Ops.push_back(Op.getOperand(i));
+
+      // We cannot use Mask (or getAllOnesMask) here as it is a scalable vector
+      // mask.
+      SDValue FixedAllOnesMask = DAG.getSplat(getMaskTypeFor(VecVT), DL,
+                                              DAG.getConstant(1, DL, XLenVT));
+      Ops.append({StackPtr, FixedAllOnesMask, VL});
+    } else {
+      unsigned Sz = Factor * VecVT.getVectorMinNumElements() *
+                    VecVT.getScalarSizeInBits();
+      EVT VecTupTy = MVT::getRISCVVectorTupleVT(Sz, Factor);
+
+      SDValue StoredVal = DAG.getUNDEF(VecTupTy);
+      for (unsigned i = 0; i < Factor; i++)
+        StoredVal = DAG.getNode(RISCVISD::TUPLE_INSERT, DL, VecTupTy, StoredVal,
+                                Op.getOperand(i),
+                                DAG.getTargetConstant(i, DL, MVT::i32));
----------------
lukel97 wrote:

But I think that works with the `VecVT`-sized stack allocation already right? `StackPtr` would still be `VecVT` sized and we already take `Mask` and `VL` from `getDefaultVLOps(VecVT, ContainerVecVT, DL, DAG, Subtarget)`, so the scalable segmented store should still be `VecVT` sized

https://github.com/llvm/llvm-project/pull/212642


More information about the llvm-commits mailing list