Skip to content

Commit 595f4f7

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 84be954 commit 595f4f7

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
}
@@ -8872,8 +8864,7 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
88728864
MVT VT = Op->getSimpleValueType(0);
88738865
MVT ContainerVT = getContainerForFixedLengthVector(VT);
88748866

8875-
SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG,
8876-
Subtarget);
8867+
SDValue VL = getVLOp(VT.getVectorNumElements(), DL, DAG, Subtarget);
88778868
SDValue IntID = DAG.getTargetConstant(VlsegInts[NF - 2], DL, XLenVT);
88788869
auto *Load = cast<MemIntrinsicSDNode>(Op);
88798870
SmallVector<EVT, 9> ContainerVTs(NF, ContainerVT);
@@ -8993,8 +8984,7 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_VOID(SDValue Op,
89938984
MVT VT = Op->getOperand(2).getSimpleValueType();
89948985
MVT ContainerVT = getContainerForFixedLengthVector(VT);
89958986

8996-
SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG,
8997-
Subtarget);
8987+
SDValue VL = getVLOp(VT.getVectorNumElements(), DL, DAG, Subtarget);
89988988
SDValue IntID = DAG.getTargetConstant(VssegInts[NF - 2], DL, XLenVT);
89998989
SDValue Ptr = Op->getOperand(NF + 2);
90008990

@@ -9498,7 +9488,7 @@ SDValue RISCVTargetLowering::lowerINSERT_SUBVECTOR(SDValue Op,
94989488
// Set the vector length to only the number of elements we care about. Note
94999489
// that for slideup this includes the offset.
95009490
unsigned EndIndex = OrigIdx + SubVecVT.getVectorNumElements();
9501-
SDValue VL = getVLOp(EndIndex, ContainerVT, DL, DAG, Subtarget);
9491+
SDValue VL = getVLOp(EndIndex, DL, DAG, Subtarget);
95029492

95039493
// Use tail agnostic policy if we're inserting over Vec's tail.
95049494
unsigned Policy = RISCVII::TAIL_UNDISTURBED_MASK_UNDISTURBED;
@@ -9675,8 +9665,7 @@ SDValue RISCVTargetLowering::lowerEXTRACT_SUBVECTOR(SDValue Op,
96759665
getDefaultVLOps(VecVT, ContainerVT, DL, DAG, Subtarget).first;
96769666
// Set the vector length to only the number of elements we care about. This
96779667
// avoids sliding down elements we're going to discard straight away.
9678-
SDValue VL = getVLOp(SubVecVT.getVectorNumElements(), ContainerVT, DL, DAG,
9679-
Subtarget);
9668+
SDValue VL = getVLOp(SubVecVT.getVectorNumElements(), DL, DAG, Subtarget);
96809669
SDValue SlidedownAmt = DAG.getConstant(OrigIdx, DL, XLenVT);
96819670
SDValue Slidedown =
96829671
getVSlidedown(DAG, Subtarget, DL, ContainerVT,
@@ -10096,7 +10085,7 @@ RISCVTargetLowering::lowerFixedLengthVectorLoadToRVV(SDValue Op,
1009610085
return DAG.getMergeValues({Result, NewLoad.getValue(1)}, DL);
1009710086
}
1009810087

10099-
SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG, Subtarget);
10088+
SDValue VL = getVLOp(VT.getVectorNumElements(), DL, DAG, Subtarget);
1010010089

1010110090
bool IsMaskOp = VT.getVectorElementType() == MVT::i1;
1010210091
SDValue IntID = DAG.getTargetConstant(
@@ -10153,8 +10142,7 @@ RISCVTargetLowering::lowerFixedLengthVectorStoreToRVV(SDValue Op,
1015310142
return DAG.getStore(Store->getChain(), DL, NewValue, Store->getBasePtr(),
1015410143
Store->getMemOperand());
1015510144

10156-
SDValue VL = getVLOp(VT.getVectorNumElements(), ContainerVT, DL, DAG,
10157-
Subtarget);
10145+
SDValue VL = getVLOp(VT.getVectorNumElements(), DL, DAG, Subtarget);
1015810146

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