Skip to content

Commit f5c7b2e

Browse files
committed
[RISCV] Move exact VLEN VLMAX encoding to RISCVInsertVSETVLI. NFC-ish
In llvm#75412 and llvm#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 f3b495f commit f5c7b2e

File tree

2 files changed

+23
-23
lines changed

2 files changed

+23
-23
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2592,16 +2592,8 @@ static SDValue getAllOnesMask(MVT VecVT, SDValue VL, const SDLoc &DL,
25922592
return DAG.getNode(RISCVISD::VMSET_VL, DL, MaskVT, VL);
25932593
}
25942594

2595-
static SDValue getVLOp(uint64_t NumElts, MVT ContainerVT, const SDLoc &DL,
2596-
SelectionDAG &DAG, const RISCVSubtarget &Subtarget) {
2597-
// If we know the exact VLEN, and our VL is exactly equal to VLMAX,
2598-
// canonicalize the representation. InsertVSETVLI will pick the immediate
2599-
// encoding later if profitable.
2600-
const auto [MinVLMAX, MaxVLMAX] =
2601-
RISCVTargetLowering::computeVLMAXBounds(ContainerVT, Subtarget);
2602-
if (MinVLMAX == MaxVLMAX && NumElts == MinVLMAX)
2603-
return DAG.getRegister(RISCV::X0, Subtarget.getXLenVT());
2604-
2595+
static SDValue getVLOp(uint64_t NumElts, const SDLoc &DL, SelectionDAG &DAG,
2596+
const RISCVSubtarget &Subtarget) {
26052597
return DAG.getConstant(NumElts, DL, Subtarget.getXLenVT());
26062598
}
26072599

@@ -2618,7 +2610,7 @@ static std::pair<SDValue, SDValue>
26182610
getDefaultVLOps(uint64_t NumElts, MVT ContainerVT, const SDLoc &DL,
26192611
SelectionDAG &DAG, const RISCVSubtarget &Subtarget) {
26202612
assert(ContainerVT.isScalableVector() && "Expecting scalable container type");
2621-
SDValue VL = getVLOp(NumElts, ContainerVT, DL, DAG, Subtarget);
2613+
SDValue VL = getVLOp(NumElts, DL, DAG, Subtarget);
26222614
SDValue Mask = getAllOnesMask(ContainerVT, VL, DL, DAG);
26232615
return {Mask, VL};
26242616
}
@@ -8908,8 +8900,7 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
89088900
MVT VT = Op->getSimpleValueType(0);
89098901
MVT ContainerVT = getContainerForFixedLengthVector(VT);
89108902

8911-
SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG,
8912-
Subtarget);
8903+
SDValue VL = getVLOp(VT.getVectorNumElements(), DL, DAG, Subtarget);
89138904
SDValue IntID = DAG.getTargetConstant(VlsegInts[NF - 2], DL, XLenVT);
89148905
auto *Load = cast<MemIntrinsicSDNode>(Op);
89158906
SmallVector<EVT, 9> ContainerVTs(NF, ContainerVT);
@@ -9029,8 +9020,7 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_VOID(SDValue Op,
90299020
MVT VT = Op->getOperand(2).getSimpleValueType();
90309021
MVT ContainerVT = getContainerForFixedLengthVector(VT);
90319022

9032-
SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG,
9033-
Subtarget);
9023+
SDValue VL = getVLOp(VT.getVectorNumElements(), DL, DAG, Subtarget);
90349024
SDValue IntID = DAG.getTargetConstant(VssegInts[NF - 2], DL, XLenVT);
90359025
SDValue Ptr = Op->getOperand(NF + 2);
90369026

@@ -9534,7 +9524,7 @@ SDValue RISCVTargetLowering::lowerINSERT_SUBVECTOR(SDValue Op,
95349524
// Set the vector length to only the number of elements we care about. Note
95359525
// that for slideup this includes the offset.
95369526
unsigned EndIndex = OrigIdx + SubVecVT.getVectorNumElements();
9537-
SDValue VL = getVLOp(EndIndex, ContainerVT, DL, DAG, Subtarget);
9527+
SDValue VL = getVLOp(EndIndex, DL, DAG, Subtarget);
95389528

95399529
// Use tail agnostic policy if we're inserting over Vec's tail.
95409530
unsigned Policy = RISCVII::TAIL_UNDISTURBED_MASK_UNDISTURBED;
@@ -9711,8 +9701,7 @@ SDValue RISCVTargetLowering::lowerEXTRACT_SUBVECTOR(SDValue Op,
97119701
getDefaultVLOps(VecVT, ContainerVT, DL, DAG, Subtarget).first;
97129702
// Set the vector length to only the number of elements we care about. This
97139703
// avoids sliding down elements we're going to discard straight away.
9714-
SDValue VL = getVLOp(SubVecVT.getVectorNumElements(), ContainerVT, DL, DAG,
9715-
Subtarget);
9704+
SDValue VL = getVLOp(SubVecVT.getVectorNumElements(), DL, DAG, Subtarget);
97169705
SDValue SlidedownAmt = DAG.getConstant(OrigIdx, DL, XLenVT);
97179706
SDValue Slidedown =
97189707
getVSlidedown(DAG, Subtarget, DL, ContainerVT,
@@ -10132,7 +10121,7 @@ RISCVTargetLowering::lowerFixedLengthVectorLoadToRVV(SDValue Op,
1013210121
return DAG.getMergeValues({Result, NewLoad.getValue(1)}, DL);
1013310122
}
1013410123

10135-
SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG, Subtarget);
10124+
SDValue VL = getVLOp(VT.getVectorNumElements(), DL, DAG, Subtarget);
1013610125

1013710126
bool IsMaskOp = VT.getVectorElementType() == MVT::i1;
1013810127
SDValue IntID = DAG.getTargetConstant(
@@ -10189,8 +10178,7 @@ RISCVTargetLowering::lowerFixedLengthVectorStoreToRVV(SDValue Op,
1018910178
return DAG.getStore(Store->getChain(), DL, NewValue, Store->getBasePtr(),
1019010179
Store->getMemOperand());
1019110180

10192-
SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG,
10193-
Subtarget);
10181+
SDValue VL = getVLOp(VT.getVectorNumElements(), DL, DAG, Subtarget);
1019410182

1019510183
bool IsMaskOp = VT.getVectorElementType() == MVT::i1;
1019610184
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)