Skip to content

Commit 6a8d675

Browse files
committed
[RISCV] Move exact VLEN VLMAX encoding to RISCVInsertVSETVLI. NFC-ish
In #75412 and #75509 we started to use the vsetvli a0, zero encoding to reduce register pressure when we know the exact VLEN. We do this by canonicalizing VL ops to X0 in RISCVISelLowering. This is only needed for cases where the AVL doesn't fit inside an immediate though, since we already have code in RISCVInsertVSETVLI that detects if we know the exact VLEN and uses the immediate encoding if possible. This patch removes the need to do the canonicalization in RISCVISelLowering by handling said case in RISCVInsertVSETVLI itself. There are a handful of reasons I'm proposing to do this: - It keeps the vsetvli logic in the one pass - We get to move code out of SelectionDAG so we don't forget about it in GlobalISEL when the time comes - Canonicalizing the VL in RISCVISelLowering means that we lose the original VL for fixed length vectors, which might be useful information for passes that sit between lowering and RISCVInsertVSETVLI. (I discovered this when working on a patch for RISCVFoldMasks.cpp that worked on fixed length vectors)
1 parent e899641 commit 6a8d675

File tree

2 files changed

+24
-25
lines changed

2 files changed

+24
-25
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2640,16 +2640,8 @@ static SDValue getAllOnesMask(MVT VecVT, SDValue VL, const SDLoc &DL,
26402640
return DAG.getNode(RISCVISD::VMSET_VL, DL, MaskVT, VL);
26412641
}
26422642

2643-
static SDValue getVLOp(uint64_t NumElts, MVT ContainerVT, const SDLoc &DL,
2644-
SelectionDAG &DAG, const RISCVSubtarget &Subtarget) {
2645-
// If we know the exact VLEN, and our VL is exactly equal to VLMAX,
2646-
// canonicalize the representation. InsertVSETVLI will pick the immediate
2647-
// encoding later if profitable.
2648-
const auto [MinVLMAX, MaxVLMAX] =
2649-
RISCVTargetLowering::computeVLMAXBounds(ContainerVT, Subtarget);
2650-
if (MinVLMAX == MaxVLMAX && NumElts == MinVLMAX)
2651-
return DAG.getRegister(RISCV::X0, Subtarget.getXLenVT());
2652-
2643+
static SDValue getVLOp(uint64_t NumElts, const SDLoc &DL, SelectionDAG &DAG,
2644+
const RISCVSubtarget &Subtarget) {
26532645
return DAG.getConstant(NumElts, DL, Subtarget.getXLenVT());
26542646
}
26552647

@@ -2666,7 +2658,7 @@ static std::pair<SDValue, SDValue>
26662658
getDefaultVLOps(uint64_t NumElts, MVT ContainerVT, const SDLoc &DL,
26672659
SelectionDAG &DAG, const RISCVSubtarget &Subtarget) {
26682660
assert(ContainerVT.isScalableVector() && "Expecting scalable container type");
2669-
SDValue VL = getVLOp(NumElts, ContainerVT, DL, DAG, Subtarget);
2661+
SDValue VL = getVLOp(NumElts, DL, DAG, Subtarget);
26702662
SDValue Mask = getAllOnesMask(ContainerVT, VL, DL, DAG);
26712663
return {Mask, VL};
26722664
}
@@ -9087,8 +9079,7 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
90879079
MVT VT = Op->getSimpleValueType(0);
90889080
MVT ContainerVT = getContainerForFixedLengthVector(VT);
90899081

9090-
SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG,
9091-
Subtarget);
9082+
SDValue VL = getVLOp(VT.getVectorNumElements(), DL, DAG, Subtarget);
90929083
SDValue IntID = DAG.getTargetConstant(VlsegInts[NF - 2], DL, XLenVT);
90939084
auto *Load = cast<MemIntrinsicSDNode>(Op);
90949085
SmallVector<EVT, 9> ContainerVTs(NF, ContainerVT);
@@ -9208,8 +9199,7 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_VOID(SDValue Op,
92089199
MVT VT = Op->getOperand(2).getSimpleValueType();
92099200
MVT ContainerVT = getContainerForFixedLengthVector(VT);
92109201

9211-
SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG,
9212-
Subtarget);
9202+
SDValue VL = getVLOp(VT.getVectorNumElements(), DL, DAG, Subtarget);
92139203
SDValue IntID = DAG.getTargetConstant(VssegInts[NF - 2], DL, XLenVT);
92149204
SDValue Ptr = Op->getOperand(NF + 2);
92159205

@@ -9625,7 +9615,7 @@ SDValue RISCVTargetLowering::lowerINSERT_SUBVECTOR(SDValue Op,
96259615
// Set the vector length to only the number of elements we care about. Note
96269616
// that for slideup this includes the offset.
96279617
unsigned EndIndex = OrigIdx + SubVecVT.getVectorNumElements();
9628-
SDValue VL = getVLOp(EndIndex, ContainerVT, DL, DAG, Subtarget);
9618+
SDValue VL = getVLOp(EndIndex, DL, DAG, Subtarget);
96299619

96309620
// Use tail agnostic policy if we're inserting over Vec's tail.
96319621
unsigned Policy = RISCVII::TAIL_UNDISTURBED_MASK_UNDISTURBED;
@@ -9805,8 +9795,7 @@ SDValue RISCVTargetLowering::lowerEXTRACT_SUBVECTOR(SDValue Op,
98059795
getDefaultVLOps(VecVT, ContainerVT, DL, DAG, Subtarget).first;
98069796
// Set the vector length to only the number of elements we care about. This
98079797
// avoids sliding down elements we're going to discard straight away.
9808-
SDValue VL = getVLOp(SubVecVT.getVectorNumElements(), ContainerVT, DL, DAG,
9809-
Subtarget);
9798+
SDValue VL = getVLOp(SubVecVT.getVectorNumElements(), DL, DAG, Subtarget);
98109799
SDValue SlidedownAmt = DAG.getConstant(OrigIdx, DL, XLenVT);
98119800
SDValue Slidedown =
98129801
getVSlidedown(DAG, Subtarget, DL, ContainerVT,
@@ -9881,8 +9870,7 @@ SDValue RISCVTargetLowering::lowerEXTRACT_SUBVECTOR(SDValue Op,
98819870
SDValue SlidedownAmt = DAG.getElementCount(DL, XLenVT, RemIdx);
98829871
auto [Mask, VL] = getDefaultScalableVLOps(InterSubVT, DL, DAG, Subtarget);
98839872
if (SubVecVT.isFixedLengthVector())
9884-
VL = getVLOp(SubVecVT.getVectorNumElements(), InterSubVT, DL, DAG,
9885-
Subtarget);
9873+
VL = getVLOp(SubVecVT.getVectorNumElements(), DL, DAG, Subtarget);
98869874
SDValue Slidedown =
98879875
getVSlidedown(DAG, Subtarget, DL, InterSubVT, DAG.getUNDEF(InterSubVT),
98889876
Vec, SlidedownAmt, Mask, VL);
@@ -10261,7 +10249,7 @@ RISCVTargetLowering::lowerFixedLengthVectorLoadToRVV(SDValue Op,
1026110249
return DAG.getMergeValues({Result, NewLoad.getValue(1)}, DL);
1026210250
}
1026310251

10264-
SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG, Subtarget);
10252+
SDValue VL = getVLOp(VT.getVectorNumElements(), DL, DAG, Subtarget);
1026510253

1026610254
bool IsMaskOp = VT.getVectorElementType() == MVT::i1;
1026710255
SDValue IntID = DAG.getTargetConstant(
@@ -10318,8 +10306,7 @@ RISCVTargetLowering::lowerFixedLengthVectorStoreToRVV(SDValue Op,
1031810306
return DAG.getStore(Store->getChain(), DL, NewValue, Store->getBasePtr(),
1031910307
Store->getMemOperand());
1032010308

10321-
SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG,
10322-
Subtarget);
10309+
SDValue VL = getVLOp(VT.getVectorNumElements(), DL, DAG, Subtarget);
1032310310

1032410311
bool IsMaskOp = VT.getVectorElementType() == MVT::i1;
1032510312
SDValue IntID = DAG.getTargetConstant(

llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -858,13 +858,14 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
858858

859859
if (RISCVII::hasVLOp(TSFlags)) {
860860
const MachineOperand &VLOp = MI.getOperand(getVLOpNum(MI));
861+
const unsigned VLMAX = computeVLMAX(ST.getRealMaxVLen(), SEW, VLMul);
862+
861863
if (VLOp.isImm()) {
862864
int64_t Imm = VLOp.getImm();
863865
// Conver the VLMax sentintel to X0 register.
864866
if (Imm == RISCV::VLMaxSentinel) {
865867
// If we know the exact VLEN, see if we can use the constant encoding
866868
// for the VLMAX instead. This reduces register pressure slightly.
867-
const unsigned VLMAX = computeVLMAX(ST.getRealMaxVLen(), SEW, VLMul);
868869
if (ST.getRealMinVLen() == ST.getRealMaxVLen() && VLMAX <= 31)
869870
InstrInfo.setAVLImm(VLMAX);
870871
else
@@ -873,7 +874,18 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
873874
else
874875
InstrInfo.setAVLImm(Imm);
875876
} else {
876-
InstrInfo.setAVLReg(VLOp.getReg());
877+
Register Reg = VLOp.getReg();
878+
// If VL is a register, it may be a materialized constant that didn't fit
879+
// into an uimm5. If we also know the exact VLEN, and the VL is equal to
880+
// the exact VLEN, use the X0 encoding so we don't need the ADDI.
881+
// doLocalPostpass will remove the ADDI if it's dead.
882+
if (ST.getRealMinVLen() == ST.getRealMaxVLen() &&
883+
VLOp.getReg().isVirtual())
884+
if (auto *VLDef = MRI->getVRegDef(VLOp.getReg());
885+
VLDef && isNonZeroLoadImmediate(*VLDef) &&
886+
VLDef->getOperand(2).getImm() == VLMAX)
887+
Reg = RISCV::X0;
888+
InstrInfo.setAVLReg(Reg);
877889
}
878890
} else {
879891
assert(isScalarExtractInstr(MI));

0 commit comments

Comments
 (0)