[llvm] [RISCV] Avoid early split for fixed-length VECTOR_DEINTERLEAVE (PR #226453)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 25 04:55:41 PDT 2026
https://github.com/compilersutra updated https://github.com/llvm/llvm-project/pull/226453
>From 127eaba7694a115ff0d2c105e91fbe1c564d600e Mon Sep 17 00:00:00 2001
From: compilersutra <osc at compilersutra.com>
Date: Fri, 25 Sep 2026 17:00:01 +0530
Subject: [PATCH 1/2] [RISCV] Avoid early split for fixed-length
VECTOR_DEINTERLEAVE
When the LMUL=8 limit forces a stack+vlseg path, keep the operands
intact and issue legal-sized vlseg chunks instead of splitting first.
Fixes #222938
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 139 ++++++++++++++
.../RISCV/rvv/vector-deinterleave-fixed.ll | 176 +++++++-----------
2 files changed, 206 insertions(+), 109 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7a5905fc4b3ea5..7180fc565422e2 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -14719,6 +14719,145 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op,
// If concatenating would exceed LMUL=8, we need to split.
if ((ContainerVecVT.getSizeInBits().getKnownMinValue() * Factor) >
(8 * RISCV::RVVBitsPerBlock)) {
+ // Fixed-length store+vlseg path: keep operands intact, spill them
+ // contiguously, then issue legal-sized vlseg at consecutive offsets.
+ // Avoids extract/concat tax from splitting operands first (#222938).
+ // Scalable keeps the shared recursive split below.
+ if (IsFixedVector) {
+ const unsigned NumElts = VecVT.getVectorNumElements();
+ MVT ElemVT = VecVT.getVectorElementType();
+
+ // Largest per-field element count with EMUL * NFIELDS <= 8.
+ // Only consider power-of-two lengths: useRVVForFixedLengthVectorVT
+ // rejects non-pow2 types, and MVT::getVectorVT may be invalid for
+ // arbitrary lengths.
+ unsigned ChunkElts = 0;
+ for (unsigned K = 1u << Log2_32(NumElts); K >= 1; K /= 2) {
+ MVT ChunkVT = MVT::getVectorVT(ElemVT, K);
+ if (!ChunkVT.isValid() || !ChunkVT.isFixedLengthVector() ||
+ !useRVVForFixedLengthVectorVT(ChunkVT))
+ continue;
+ MVT ChunkContainer = getContainerForFixedLengthVector(ChunkVT);
+ if (ChunkContainer.getSizeInBits().getKnownMinValue() * Factor <=
+ (8 * RISCV::RVVBitsPerBlock)) {
+ ChunkElts = K;
+ break;
+ }
+ }
+ assert(ChunkElts != 0 && "expected a legal fixed-length vlseg chunk");
+
+ MVT XLenVT = Subtarget.getXLenVT();
+ auto &MF = DAG.getMachineFunction();
+ SDValue Chain = DAG.getEntryNode();
+ Align Alignment = DAG.getReducedAlign(VecVT, /*UseABI=*/false);
+
+ ElementCount ActualConcatEC = VecVT.getVectorElementCount() * Factor;
+ EVT ConcatEVT =
+ EVT::getVectorVT(*DAG.getContext(), ElemVT, ActualConcatEC);
+ SDValue StackPtr =
+ DAG.CreateStackTemporary(ConcatEVT.getStoreSize(), Alignment);
+ auto FrameIndex = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
+ MachinePointerInfo PtrInfo =
+ MachinePointerInfo::getFixedStack(MF, FrameIndex);
+
+ TypeSize VecSize = VecVT.getStoreSize();
+ SDValue BasePtr = StackPtr;
+ MachinePointerInfo PI = PtrInfo;
+ SmallVector<SDValue, 8> Tokens(Factor);
+ for (auto [Idx, FieldOp] : enumerate(Op->op_values())) {
+ if (Idx) {
+ BasePtr = DAG.getObjectPtrOffset(DL, BasePtr, VecSize);
+ PI = PI.getWithOffset(VecSize);
+ }
+ Tokens[Idx] = DAG.getStore(Chain, DL, FieldOp, BasePtr, PI, Alignment);
+ }
+ Chain = DAG.getTokenFactor(DL, Tokens);
+
+ const unsigned ElemBytes = VecVT.getScalarStoreSize();
+
+ static const Intrinsic::ID VlsegIntrinsicsIds[] = {
+ Intrinsic::riscv_vlseg2_mask, Intrinsic::riscv_vlseg3_mask,
+ Intrinsic::riscv_vlseg4_mask, Intrinsic::riscv_vlseg5_mask,
+ Intrinsic::riscv_vlseg6_mask, Intrinsic::riscv_vlseg7_mask,
+ Intrinsic::riscv_vlseg8_mask};
+
+ SmallVector<SmallVector<SDValue, 4>, 8> Parts(Factor);
+ MVT ChunkVT = MVT::getVectorVT(ElemVT, ChunkElts);
+ MVT ChunkContainer = getContainerForFixedLengthVector(ChunkVT);
+ MVT WideVT =
+ MVT::getVectorVT(ElemVT, ChunkElts * PowerOf2Ceil(Factor));
+ assert(WideVT.isValid() && WideVT.isFixedLengthVector() &&
+ "expected legal wide passthru VT for chunked vlseg");
+ MVT WideContainer = getContainerForFixedLengthVector(WideVT);
+
+ for (unsigned Offset = 0; Offset < NumElts; Offset += ChunkElts) {
+ unsigned ThisChunkElts = std::min(ChunkElts, NumElts - Offset);
+
+ SDValue ChunkPtr = DAG.getObjectPtrOffset(
+ DL, StackPtr,
+ TypeSize::getFixed(static_cast<uint64_t>(Offset) * Factor *
+ ElemBytes));
+ MachinePointerInfo ChunkPI = PtrInfo.getWithOffset(
+ static_cast<uint64_t>(Offset) * Factor * ElemBytes);
+
+ SDValue Mask, VL;
+ std::tie(Mask, VL) =
+ getDefaultVLOps(ChunkVT, ChunkContainer, DL, DAG, Subtarget);
+ // Partial final chunk: keep the legal (pow2) container, shrink VL.
+ if (ThisChunkElts != ChunkElts)
+ VL = DAG.getConstant(ThisChunkElts, DL, XLenVT);
+
+ SDValue Passthru = DAG.getUNDEF(WideContainer);
+
+ SDValue LoadOps[] = {
+ Chain,
+ DAG.getTargetConstant(VlsegIntrinsicsIds[Factor - 2], DL, XLenVT),
+ Passthru,
+ ChunkPtr,
+ Mask,
+ VL,
+ DAG.getTargetConstant(
+ RISCVVType::TAIL_AGNOSTIC | RISCVVType::MASK_AGNOSTIC, DL,
+ XLenVT),
+ DAG.getTargetConstant(Log2_64(VecVT.getScalarSizeInBits()), DL,
+ XLenVT)};
+
+ unsigned Sz = Factor * ChunkContainer.getVectorMinNumElements() *
+ ChunkContainer.getScalarSizeInBits();
+ EVT VecTupTy = MVT::getRISCVVectorTupleVT(Sz, Factor);
+
+ SDValue Load = DAG.getMemIntrinsicNode(
+ ISD::INTRINSIC_W_CHAIN, DL, DAG.getVTList({VecTupTy, MVT::Other}),
+ LoadOps, ElemVT, ChunkPI, Alignment, MachineMemOperand::MOLoad,
+ LocationSize::beforeOrAfterPointer());
+ Chain = Load.getValue(1);
+
+ for (unsigned i = 0; i != Factor; ++i) {
+ SDValue FieldRes =
+ DAG.getNode(RISCVISD::TUPLE_EXTRACT, DL, ChunkContainer, Load,
+ DAG.getTargetConstant(i, DL, MVT::i32));
+ SDValue Fixed = convertFromScalableVector(ChunkVT, FieldRes, DAG,
+ Subtarget);
+ if (ThisChunkElts != ChunkElts) {
+ EVT NarrowVT =
+ EVT::getVectorVT(*DAG.getContext(), ElemVT, ThisChunkElts);
+ Fixed = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, NarrowVT, Fixed,
+ DAG.getVectorIdxConstant(0, DL));
+ }
+ Parts[i].push_back(Fixed);
+ }
+ }
+
+ SmallVector<SDValue, 8> Res(Factor);
+ for (unsigned i = 0; i != Factor; ++i) {
+ if (Parts[i].size() == 1)
+ Res[i] = Parts[i][0];
+ else
+ Res[i] = DAG.getNode(ISD::CONCAT_VECTORS, DL, VecVT, Parts[i]);
+ }
+ return DAG.getMergeValues(Res, DL);
+ }
+
SmallVector<SDValue, 8> Ops(Factor * 2);
for (unsigned i = 0; i != Factor; ++i) {
auto [OpLo, OpHi] = DAG.SplitVectorOperand(Op.getNode(), i);
diff --git a/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll b/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll
index bce071e988f0ef..1ea3769b7f621b 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll
@@ -231,38 +231,38 @@ define {<15 x i32>, <15 x i32>, <15 x i32>} @vector_deinterleave3_v15i32_v45i32(
; RV32-NEXT: sw s0, 632(sp) # 4-byte Folded Spill
; RV32-NEXT: addi s0, sp, 640
; RV32-NEXT: andi sp, sp, -128
-; RV32-NEXT: addi a1, sp, 252
+; RV32-NEXT: addi a1, sp, 60
; RV32-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; RV32-NEXT: vse32.v v23, (a1)
-; RV32-NEXT: addi a1, sp, 248
+; RV32-NEXT: addi a1, sp, 56
; RV32-NEXT: vse32.v v22, (a1)
-; RV32-NEXT: addi a1, sp, 244
+; RV32-NEXT: addi a1, sp, 52
; RV32-NEXT: vse32.v v21, (a1)
-; RV32-NEXT: addi a1, sp, 240
+; RV32-NEXT: addi a1, sp, 48
; RV32-NEXT: vse32.v v20, (a1)
-; RV32-NEXT: addi a1, sp, 236
+; RV32-NEXT: addi a1, sp, 44
; RV32-NEXT: vse32.v v19, (a1)
-; RV32-NEXT: addi a1, sp, 232
+; RV32-NEXT: addi a1, sp, 40
; RV32-NEXT: vse32.v v18, (a1)
-; RV32-NEXT: addi a1, sp, 228
+; RV32-NEXT: addi a1, sp, 36
; RV32-NEXT: vse32.v v17, (a1)
-; RV32-NEXT: addi a1, sp, 224
+; RV32-NEXT: addi a1, sp, 32
; RV32-NEXT: vse32.v v16, (a1)
-; RV32-NEXT: addi a1, sp, 220
+; RV32-NEXT: addi a1, sp, 28
; RV32-NEXT: vse32.v v15, (a1)
-; RV32-NEXT: addi a1, sp, 216
+; RV32-NEXT: addi a1, sp, 24
; RV32-NEXT: vse32.v v14, (a1)
-; RV32-NEXT: addi a1, sp, 212
+; RV32-NEXT: addi a1, sp, 20
; RV32-NEXT: vse32.v v13, (a1)
-; RV32-NEXT: addi a1, sp, 208
+; RV32-NEXT: addi a1, sp, 16
; RV32-NEXT: vse32.v v12, (a1)
-; RV32-NEXT: addi a1, sp, 204
+; RV32-NEXT: addi a1, sp, 12
; RV32-NEXT: vse32.v v11, (a1)
-; RV32-NEXT: addi a1, sp, 200
+; RV32-NEXT: addi a1, sp, 8
; RV32-NEXT: vse32.v v10, (a1)
-; RV32-NEXT: addi a1, sp, 196
+; RV32-NEXT: addi a1, sp, 4
; RV32-NEXT: vse32.v v9, (a1)
-; RV32-NEXT: addi a1, sp, 192
+; RV32-NEXT: mv a1, sp
; RV32-NEXT: vse32.v v8, (a1)
; RV32-NEXT: addi a2, a0, 64
; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma
@@ -276,33 +276,19 @@ define {<15 x i32>, <15 x i32>, <15 x i32>} @vector_deinterleave3_v15i32_v45i32(
; RV32-NEXT: vse32.v v8, (a3)
; RV32-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; RV32-NEXT: vle32.v v8, (a0)
-; RV32-NEXT: addi a3, sp, 64
-; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma
-; RV32-NEXT: vse32.v v8, (a3)
-; RV32-NEXT: vsetivli zero, 16, e32, m4, ta, ma
-; RV32-NEXT: vle32.v v12, (a1)
-; RV32-NEXT: vsetivli zero, 8, e32, m4, ta, ma
-; RV32-NEXT: vslidedown.vi v16, v12, 8
-; RV32-NEXT: mv a1, sp
-; RV32-NEXT: vslidedown.vi v8, v8, 8
-; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma
-; RV32-NEXT: vse32.v v12, (a1)
-; RV32-NEXT: addi a3, sp, 32
-; RV32-NEXT: vse32.v v16, (a3)
-; RV32-NEXT: addi a3, sp, 96
+; RV32-NEXT: addi a3, sp, 128
; RV32-NEXT: vse32.v v8, (a3)
+; RV32-NEXT: vle32.v v8, (a1)
+; RV32-NEXT: addi a1, sp, 64
+; RV32-NEXT: vse32.v v8, (a1)
; RV32-NEXT: lw a0, 112(a0)
; RV32-NEXT: sw a0, 432(sp)
-; RV32-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; RV32-NEXT: vle32.v v8, (a2)
-; RV32-NEXT: vsetivli zero, 8, e32, m4, ta, ma
-; RV32-NEXT: vslidedown.vi v12, v8, 8
-; RV32-NEXT: addi a0, sp, 128
-; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; RV32-NEXT: addi a0, sp, 192
; RV32-NEXT: vse32.v v8, (a0)
; RV32-NEXT: addi a0, sp, 160
-; RV32-NEXT: vse32.v v12, (a0)
-; RV32-NEXT: vlseg3e32.v v20, (a3)
+; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; RV32-NEXT: vlseg3e32.v v20, (a0)
; RV32-NEXT: vlseg3e32.v v12, (a1)
; RV32-NEXT: vmv4r.v v28, v20
; RV32-NEXT: vmv2r.v v30, v8
@@ -329,37 +315,37 @@ define {<15 x i32>, <15 x i32>, <15 x i32>} @vector_deinterleave3_v15i32_v45i32(
; RV64-NEXT: addi a1, a0, 112
; RV64-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; RV64-NEXT: vle32.v v24, (a1)
-; RV64-NEXT: addi a1, sp, 252
+; RV64-NEXT: addi a1, sp, 60
; RV64-NEXT: vse32.v v23, (a1)
-; RV64-NEXT: addi a1, sp, 248
+; RV64-NEXT: addi a1, sp, 56
; RV64-NEXT: vse32.v v22, (a1)
-; RV64-NEXT: addi a1, sp, 244
+; RV64-NEXT: addi a1, sp, 52
; RV64-NEXT: vse32.v v21, (a1)
-; RV64-NEXT: addi a1, sp, 240
+; RV64-NEXT: addi a1, sp, 48
; RV64-NEXT: vse32.v v20, (a1)
-; RV64-NEXT: addi a1, sp, 236
+; RV64-NEXT: addi a1, sp, 44
; RV64-NEXT: vse32.v v19, (a1)
-; RV64-NEXT: addi a1, sp, 232
+; RV64-NEXT: addi a1, sp, 40
; RV64-NEXT: vse32.v v18, (a1)
-; RV64-NEXT: addi a1, sp, 228
+; RV64-NEXT: addi a1, sp, 36
; RV64-NEXT: vse32.v v17, (a1)
-; RV64-NEXT: addi a1, sp, 224
+; RV64-NEXT: addi a1, sp, 32
; RV64-NEXT: vse32.v v16, (a1)
-; RV64-NEXT: addi a1, sp, 220
+; RV64-NEXT: addi a1, sp, 28
; RV64-NEXT: vse32.v v15, (a1)
-; RV64-NEXT: addi a1, sp, 216
+; RV64-NEXT: addi a1, sp, 24
; RV64-NEXT: vse32.v v14, (a1)
-; RV64-NEXT: addi a1, sp, 212
+; RV64-NEXT: addi a1, sp, 20
; RV64-NEXT: vse32.v v13, (a1)
-; RV64-NEXT: addi a1, sp, 208
+; RV64-NEXT: addi a1, sp, 16
; RV64-NEXT: vse32.v v12, (a1)
-; RV64-NEXT: addi a1, sp, 204
+; RV64-NEXT: addi a1, sp, 12
; RV64-NEXT: vse32.v v11, (a1)
-; RV64-NEXT: addi a1, sp, 200
+; RV64-NEXT: addi a1, sp, 8
; RV64-NEXT: vse32.v v10, (a1)
-; RV64-NEXT: addi a1, sp, 196
+; RV64-NEXT: addi a1, sp, 4
; RV64-NEXT: vse32.v v9, (a1)
-; RV64-NEXT: addi a1, sp, 192
+; RV64-NEXT: mv a1, sp
; RV64-NEXT: vse32.v v8, (a1)
; RV64-NEXT: addi a2, a0, 64
; RV64-NEXT: vsetivli zero, 8, e32, m2, ta, ma
@@ -376,30 +362,16 @@ define {<15 x i32>, <15 x i32>, <15 x i32>} @vector_deinterleave3_v15i32_v45i32(
; RV64-NEXT: vse32.v v24, (a3)
; RV64-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; RV64-NEXT: vle32.v v8, (a0)
+; RV64-NEXT: addi a0, sp, 128
+; RV64-NEXT: vse32.v v8, (a0)
+; RV64-NEXT: vle32.v v8, (a1)
; RV64-NEXT: addi a0, sp, 64
-; RV64-NEXT: vsetivli zero, 8, e32, m2, ta, ma
; RV64-NEXT: vse32.v v8, (a0)
-; RV64-NEXT: vsetivli zero, 16, e32, m4, ta, ma
-; RV64-NEXT: vle32.v v12, (a1)
-; RV64-NEXT: vsetivli zero, 8, e32, m4, ta, ma
-; RV64-NEXT: vslidedown.vi v16, v12, 8
-; RV64-NEXT: mv a0, sp
-; RV64-NEXT: vslidedown.vi v8, v8, 8
-; RV64-NEXT: vsetivli zero, 8, e32, m2, ta, ma
-; RV64-NEXT: vse32.v v12, (a0)
-; RV64-NEXT: addi a1, sp, 32
-; RV64-NEXT: vse32.v v16, (a1)
-; RV64-NEXT: addi a1, sp, 96
-; RV64-NEXT: vse32.v v8, (a1)
-; RV64-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; RV64-NEXT: vle32.v v8, (a2)
-; RV64-NEXT: vsetivli zero, 8, e32, m4, ta, ma
-; RV64-NEXT: vslidedown.vi v12, v8, 8
-; RV64-NEXT: addi a2, sp, 128
+; RV64-NEXT: addi a1, sp, 192
+; RV64-NEXT: vse32.v v8, (a1)
+; RV64-NEXT: addi a1, sp, 160
; RV64-NEXT: vsetivli zero, 8, e32, m2, ta, ma
-; RV64-NEXT: vse32.v v8, (a2)
-; RV64-NEXT: addi a2, sp, 160
-; RV64-NEXT: vse32.v v12, (a2)
; RV64-NEXT: vlseg3e32.v v20, (a1)
; RV64-NEXT: vlseg3e32.v v12, (a0)
; RV64-NEXT: vmv4r.v v28, v20
@@ -427,37 +399,37 @@ define {<15 x i32>, <15 x i32>, <15 x i32>} @vector_deinterleave3_v15i32_v45i32(
; ZVZIP-NEXT: addi a1, a0, 112
; ZVZIP-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
; ZVZIP-NEXT: vle32.v v24, (a1)
-; ZVZIP-NEXT: addi a1, sp, 252
+; ZVZIP-NEXT: addi a1, sp, 60
; ZVZIP-NEXT: vse32.v v23, (a1)
-; ZVZIP-NEXT: addi a1, sp, 248
+; ZVZIP-NEXT: addi a1, sp, 56
; ZVZIP-NEXT: vse32.v v22, (a1)
-; ZVZIP-NEXT: addi a1, sp, 244
+; ZVZIP-NEXT: addi a1, sp, 52
; ZVZIP-NEXT: vse32.v v21, (a1)
-; ZVZIP-NEXT: addi a1, sp, 240
+; ZVZIP-NEXT: addi a1, sp, 48
; ZVZIP-NEXT: vse32.v v20, (a1)
-; ZVZIP-NEXT: addi a1, sp, 236
+; ZVZIP-NEXT: addi a1, sp, 44
; ZVZIP-NEXT: vse32.v v19, (a1)
-; ZVZIP-NEXT: addi a1, sp, 232
+; ZVZIP-NEXT: addi a1, sp, 40
; ZVZIP-NEXT: vse32.v v18, (a1)
-; ZVZIP-NEXT: addi a1, sp, 228
+; ZVZIP-NEXT: addi a1, sp, 36
; ZVZIP-NEXT: vse32.v v17, (a1)
-; ZVZIP-NEXT: addi a1, sp, 224
+; ZVZIP-NEXT: addi a1, sp, 32
; ZVZIP-NEXT: vse32.v v16, (a1)
-; ZVZIP-NEXT: addi a1, sp, 220
+; ZVZIP-NEXT: addi a1, sp, 28
; ZVZIP-NEXT: vse32.v v15, (a1)
-; ZVZIP-NEXT: addi a1, sp, 216
+; ZVZIP-NEXT: addi a1, sp, 24
; ZVZIP-NEXT: vse32.v v14, (a1)
-; ZVZIP-NEXT: addi a1, sp, 212
+; ZVZIP-NEXT: addi a1, sp, 20
; ZVZIP-NEXT: vse32.v v13, (a1)
-; ZVZIP-NEXT: addi a1, sp, 208
+; ZVZIP-NEXT: addi a1, sp, 16
; ZVZIP-NEXT: vse32.v v12, (a1)
-; ZVZIP-NEXT: addi a1, sp, 204
+; ZVZIP-NEXT: addi a1, sp, 12
; ZVZIP-NEXT: vse32.v v11, (a1)
-; ZVZIP-NEXT: addi a1, sp, 200
+; ZVZIP-NEXT: addi a1, sp, 8
; ZVZIP-NEXT: vse32.v v10, (a1)
-; ZVZIP-NEXT: addi a1, sp, 196
+; ZVZIP-NEXT: addi a1, sp, 4
; ZVZIP-NEXT: vse32.v v9, (a1)
-; ZVZIP-NEXT: addi a1, sp, 192
+; ZVZIP-NEXT: mv a1, sp
; ZVZIP-NEXT: vse32.v v8, (a1)
; ZVZIP-NEXT: addi a2, a0, 64
; ZVZIP-NEXT: vsetivli zero, 8, e32, m2, ta, ma
@@ -474,30 +446,16 @@ define {<15 x i32>, <15 x i32>, <15 x i32>} @vector_deinterleave3_v15i32_v45i32(
; ZVZIP-NEXT: vse32.v v24, (a3)
; ZVZIP-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; ZVZIP-NEXT: vle32.v v8, (a0)
+; ZVZIP-NEXT: addi a0, sp, 128
+; ZVZIP-NEXT: vse32.v v8, (a0)
+; ZVZIP-NEXT: vle32.v v8, (a1)
; ZVZIP-NEXT: addi a0, sp, 64
-; ZVZIP-NEXT: vsetivli zero, 8, e32, m2, ta, ma
; ZVZIP-NEXT: vse32.v v8, (a0)
-; ZVZIP-NEXT: vsetivli zero, 16, e32, m4, ta, ma
-; ZVZIP-NEXT: vle32.v v12, (a1)
-; ZVZIP-NEXT: vsetivli zero, 8, e32, m4, ta, ma
-; ZVZIP-NEXT: vslidedown.vi v16, v12, 8
-; ZVZIP-NEXT: mv a0, sp
-; ZVZIP-NEXT: vslidedown.vi v8, v8, 8
-; ZVZIP-NEXT: vsetivli zero, 8, e32, m2, ta, ma
-; ZVZIP-NEXT: vse32.v v12, (a0)
-; ZVZIP-NEXT: addi a1, sp, 32
-; ZVZIP-NEXT: vse32.v v16, (a1)
-; ZVZIP-NEXT: addi a1, sp, 96
-; ZVZIP-NEXT: vse32.v v8, (a1)
-; ZVZIP-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; ZVZIP-NEXT: vle32.v v8, (a2)
-; ZVZIP-NEXT: vsetivli zero, 8, e32, m4, ta, ma
-; ZVZIP-NEXT: vslidedown.vi v12, v8, 8
-; ZVZIP-NEXT: addi a2, sp, 128
+; ZVZIP-NEXT: addi a1, sp, 192
+; ZVZIP-NEXT: vse32.v v8, (a1)
+; ZVZIP-NEXT: addi a1, sp, 160
; ZVZIP-NEXT: vsetivli zero, 8, e32, m2, ta, ma
-; ZVZIP-NEXT: vse32.v v8, (a2)
-; ZVZIP-NEXT: addi a2, sp, 160
-; ZVZIP-NEXT: vse32.v v12, (a2)
; ZVZIP-NEXT: vlseg3e32.v v20, (a1)
; ZVZIP-NEXT: vlseg3e32.v v12, (a0)
; ZVZIP-NEXT: vmv4r.v v28, v20
>From 9a4154295d8b26a022f9fe2119b66d2c3dbf65a0 Mon Sep 17 00:00:00 2001
From: compilersutra <osc at compilersutra.com>
Date: Fri, 25 Sep 2026 17:18:42 +0530
Subject: [PATCH 2/2] [RISCV] clang-format fixed-length VECTOR_DEINTERLEAVE
path
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7180fc565422e2..887288426f5ea1 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -14784,8 +14784,7 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op,
SmallVector<SmallVector<SDValue, 4>, 8> Parts(Factor);
MVT ChunkVT = MVT::getVectorVT(ElemVT, ChunkElts);
MVT ChunkContainer = getContainerForFixedLengthVector(ChunkVT);
- MVT WideVT =
- MVT::getVectorVT(ElemVT, ChunkElts * PowerOf2Ceil(Factor));
+ MVT WideVT = MVT::getVectorVT(ElemVT, ChunkElts * PowerOf2Ceil(Factor));
assert(WideVT.isValid() && WideVT.isFixedLengthVector() &&
"expected legal wide passthru VT for chunked vlseg");
MVT WideContainer = getContainerForFixedLengthVector(WideVT);
@@ -14816,9 +14815,9 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op,
ChunkPtr,
Mask,
VL,
- DAG.getTargetConstant(
- RISCVVType::TAIL_AGNOSTIC | RISCVVType::MASK_AGNOSTIC, DL,
- XLenVT),
+ DAG.getTargetConstant(RISCVVType::TAIL_AGNOSTIC |
+ RISCVVType::MASK_AGNOSTIC,
+ DL, XLenVT),
DAG.getTargetConstant(Log2_64(VecVT.getScalarSizeInBits()), DL,
XLenVT)};
@@ -14836,8 +14835,8 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op,
SDValue FieldRes =
DAG.getNode(RISCVISD::TUPLE_EXTRACT, DL, ChunkContainer, Load,
DAG.getTargetConstant(i, DL, MVT::i32));
- SDValue Fixed = convertFromScalableVector(ChunkVT, FieldRes, DAG,
- Subtarget);
+ SDValue Fixed =
+ convertFromScalableVector(ChunkVT, FieldRes, DAG, Subtarget);
if (ThisChunkElts != ChunkElts) {
EVT NarrowVT =
EVT::getVectorVT(*DAG.getContext(), ElemVT, ThisChunkElts);
More information about the llvm-commits
mailing list