Skip to content

Commit b4492c9

Browse files
authored
[RISCV] Use an enum for demanded LMUL in RISCVInsertVSETVLI. NFC (llvm#92513)
In needVSETVLI used by the forward insertion pass, we have some rules where we can relax the demanded fields for slides and splats when VL=1. However this only works if we don't increase LMUL to anything > M1 otherwise we would end up clobbering random registers. Rather than check the VSETVLIInfo we're transitioning to, store this information in DemandedFields and have isCompatible check it. That way an upcoming patch can share these VL=1 rules with RISCVCoalesceVSETVLI, which uses isCompatible and not needVSETVLI.
1 parent 8be079c commit b4492c9

File tree

1 file changed

+46
-22
lines changed

1 file changed

+46
-22
lines changed

llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,11 @@ struct DemandedFields {
215215
// than 64.
216216
SEWNone = 0 // We don't need to preserve SEW at all.
217217
} SEW = SEWNone;
218-
bool LMUL = false;
218+
enum : uint8_t {
219+
LMULEqual = 2, // The exact value of LMUL needs to be preserved.
220+
LMULLessThanOrEqualToM1 = 1, // We can use any LMUL <= M1.
221+
LMULNone = 0 // We don't need to preserve LMUL at all.
222+
} LMUL = LMULNone;
219223
bool SEWLMULRatio = false;
220224
bool TailPolicy = false;
221225
bool MaskPolicy = false;
@@ -233,7 +237,7 @@ struct DemandedFields {
233237
// Mark all VTYPE subfields and properties as demanded
234238
void demandVTYPE() {
235239
SEW = SEWEqual;
236-
LMUL = true;
240+
LMUL = LMULEqual;
237241
SEWLMULRatio = true;
238242
TailPolicy = true;
239243
MaskPolicy = true;
@@ -250,7 +254,7 @@ struct DemandedFields {
250254
VLAny |= B.VLAny;
251255
VLZeroness |= B.VLZeroness;
252256
SEW = std::max(SEW, B.SEW);
253-
LMUL |= B.LMUL;
257+
LMUL = std::max(LMUL, B.LMUL);
254258
SEWLMULRatio |= B.SEWLMULRatio;
255259
TailPolicy |= B.TailPolicy;
256260
MaskPolicy |= B.MaskPolicy;
@@ -284,7 +288,19 @@ struct DemandedFields {
284288
break;
285289
};
286290
OS << ", ";
287-
OS << "LMUL=" << LMUL << ", ";
291+
OS << "LMUL=";
292+
switch (LMUL) {
293+
case LMULEqual:
294+
OS << "LMULEqual";
295+
break;
296+
case LMULLessThanOrEqualToM1:
297+
OS << "LMULLessThanOrEqualToM1";
298+
break;
299+
case LMULNone:
300+
OS << "LMULNone";
301+
break;
302+
};
303+
OS << ", ";
288304
OS << "SEWLMULRatio=" << SEWLMULRatio << ", ";
289305
OS << "TailPolicy=" << TailPolicy << ", ";
290306
OS << "MaskPolicy=" << MaskPolicy;
@@ -301,6 +317,11 @@ inline raw_ostream &operator<<(raw_ostream &OS, const DemandedFields &DF) {
301317
}
302318
#endif
303319

320+
static bool isLMUL1OrSmaller(RISCVII::VLMUL LMUL) {
321+
auto [LMul, Fractional] = RISCVVType::decodeVLMUL(LMUL);
322+
return Fractional || LMul == 1;
323+
}
324+
304325
/// Return true if moving from CurVType to NewVType is
305326
/// indistinguishable from the perspective of an instruction (or set
306327
/// of instructions) which use only the Used subfields and properties.
@@ -324,9 +345,18 @@ static bool areCompatibleVTYPEs(uint64_t CurVType, uint64_t NewVType,
324345
break;
325346
}
326347

327-
if (Used.LMUL &&
328-
RISCVVType::getVLMUL(CurVType) != RISCVVType::getVLMUL(NewVType))
329-
return false;
348+
switch (Used.LMUL) {
349+
case DemandedFields::LMULNone:
350+
break;
351+
case DemandedFields::LMULEqual:
352+
if (RISCVVType::getVLMUL(CurVType) != RISCVVType::getVLMUL(NewVType))
353+
return false;
354+
break;
355+
case DemandedFields::LMULLessThanOrEqualToM1:
356+
if (!isLMUL1OrSmaller(RISCVVType::getVLMUL(NewVType)))
357+
return false;
358+
break;
359+
}
330360

331361
if (Used.SEWLMULRatio) {
332362
auto Ratio1 = RISCVVType::getSEWLMULRatio(RISCVVType::getSEW(CurVType),
@@ -382,7 +412,7 @@ DemandedFields getDemanded(const MachineInstr &MI, const RISCVSubtarget *ST) {
382412
// in the opcode. This is asserted when constructing the VSETVLIInfo.
383413
if (getEEWForLoadStore(MI)) {
384414
Res.SEW = DemandedFields::SEWNone;
385-
Res.LMUL = false;
415+
Res.LMUL = DemandedFields::LMULNone;
386416
}
387417

388418
// Store instructions don't use the policy fields.
@@ -397,12 +427,12 @@ DemandedFields getDemanded(const MachineInstr &MI, const RISCVSubtarget *ST) {
397427
// * The policy bits can probably be ignored..
398428
if (isMaskRegOp(MI)) {
399429
Res.SEW = DemandedFields::SEWNone;
400-
Res.LMUL = false;
430+
Res.LMUL = DemandedFields::LMULNone;
401431
}
402432

403433
// For vmv.s.x and vfmv.s.f, there are only two behaviors, VL = 0 and VL > 0.
404434
if (isScalarInsertInstr(MI)) {
405-
Res.LMUL = false;
435+
Res.LMUL = DemandedFields::LMULNone;
406436
Res.SEWLMULRatio = false;
407437
Res.VLAny = false;
408438
// For vmv.s.x and vfmv.s.f, if the merge operand is *undefined*, we don't
@@ -423,7 +453,7 @@ DemandedFields getDemanded(const MachineInstr &MI, const RISCVSubtarget *ST) {
423453
// vmv.x.s, and vmv.f.s are unconditional and ignore everything except SEW.
424454
if (isScalarExtractInstr(MI)) {
425455
assert(!RISCVII::hasVLOp(TSFlags));
426-
Res.LMUL = false;
456+
Res.LMUL = DemandedFields::LMULNone;
427457
Res.SEWLMULRatio = false;
428458
Res.TailPolicy = false;
429459
Res.MaskPolicy = false;
@@ -1107,11 +1137,6 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
11071137
LIS->getMBBStartIdx(&MBB), LIS->getInstructionIndex(*MI).getRegSlot());
11081138
}
11091139

1110-
static bool isLMUL1OrSmaller(RISCVII::VLMUL LMUL) {
1111-
auto [LMul, Fractional] = RISCVVType::decodeVLMUL(LMUL);
1112-
return Fractional || LMul == 1;
1113-
}
1114-
11151140
/// Return true if a VSETVLI is required to transition from CurInfo to Require
11161141
/// before MI.
11171142
bool RISCVInsertVSETVLI::needVSETVLI(const MachineInstr &MI,
@@ -1133,10 +1158,10 @@ bool RISCVInsertVSETVLI::needVSETVLI(const MachineInstr &MI,
11331158
// * The LMUL1 restriction is for machines whose latency may depend on VL.
11341159
// * As above, this is only legal for tail "undefined" not "agnostic".
11351160
if (isVSlideInstr(MI) && Require.hasAVLImm() && Require.getAVLImm() == 1 &&
1136-
isLMUL1OrSmaller(CurInfo.getVLMUL()) && hasUndefinedMergeOp(MI)) {
1161+
hasUndefinedMergeOp(MI)) {
11371162
Used.VLAny = false;
11381163
Used.VLZeroness = true;
1139-
Used.LMUL = false;
1164+
Used.LMUL = DemandedFields::LMULLessThanOrEqualToM1;
11401165
Used.TailPolicy = false;
11411166
}
11421167

@@ -1146,9 +1171,8 @@ bool RISCVInsertVSETVLI::needVSETVLI(const MachineInstr &MI,
11461171
// Since a splat is non-constant time in LMUL, we do need to be careful to not
11471172
// increase the number of active vector registers (unlike for vmv.s.x.)
11481173
if (isScalarSplatInstr(MI) && Require.hasAVLImm() &&
1149-
Require.getAVLImm() == 1 && isLMUL1OrSmaller(CurInfo.getVLMUL()) &&
1150-
hasUndefinedMergeOp(MI)) {
1151-
Used.LMUL = false;
1174+
Require.getAVLImm() == 1 && hasUndefinedMergeOp(MI)) {
1175+
Used.LMUL = DemandedFields::LMULLessThanOrEqualToM1;
11521176
Used.SEWLMULRatio = false;
11531177
Used.VLAny = false;
11541178
if (isFloatScalarMoveOrScalarSplatInstr(MI) && !ST->hasVInstructionsF64())
@@ -1189,7 +1213,7 @@ static VSETVLIInfo adjustIncoming(VSETVLIInfo PrevInfo, VSETVLIInfo NewInfo,
11891213
if (auto NewVLMul = RISCVVType::getSameRatioLMUL(
11901214
PrevInfo.getSEW(), PrevInfo.getVLMUL(), Info.getSEW()))
11911215
Info.setVLMul(*NewVLMul);
1192-
Demanded.LMUL = true;
1216+
Demanded.LMUL = DemandedFields::LMULEqual;
11931217
}
11941218

11951219
return Info;

0 commit comments

Comments
 (0)