@@ -215,7 +215,11 @@ struct DemandedFields {
215
215
// than 64.
216
216
SEWNone = 0 // We don't need to preserve SEW at all.
217
217
} 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;
219
223
bool SEWLMULRatio = false ;
220
224
bool TailPolicy = false ;
221
225
bool MaskPolicy = false ;
@@ -233,7 +237,7 @@ struct DemandedFields {
233
237
// Mark all VTYPE subfields and properties as demanded
234
238
void demandVTYPE () {
235
239
SEW = SEWEqual;
236
- LMUL = true ;
240
+ LMUL = LMULEqual ;
237
241
SEWLMULRatio = true ;
238
242
TailPolicy = true ;
239
243
MaskPolicy = true ;
@@ -250,7 +254,7 @@ struct DemandedFields {
250
254
VLAny |= B.VLAny ;
251
255
VLZeroness |= B.VLZeroness ;
252
256
SEW = std::max (SEW, B.SEW );
253
- LMUL |= B.LMUL ;
257
+ LMUL = std::max (LMUL, B.LMUL ) ;
254
258
SEWLMULRatio |= B.SEWLMULRatio ;
255
259
TailPolicy |= B.TailPolicy ;
256
260
MaskPolicy |= B.MaskPolicy ;
@@ -284,7 +288,19 @@ struct DemandedFields {
284
288
break ;
285
289
};
286
290
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 << " , " ;
288
304
OS << " SEWLMULRatio=" << SEWLMULRatio << " , " ;
289
305
OS << " TailPolicy=" << TailPolicy << " , " ;
290
306
OS << " MaskPolicy=" << MaskPolicy;
@@ -301,6 +317,11 @@ inline raw_ostream &operator<<(raw_ostream &OS, const DemandedFields &DF) {
301
317
}
302
318
#endif
303
319
320
+ static bool isLMUL1OrSmaller (RISCVII::VLMUL LMUL) {
321
+ auto [LMul, Fractional] = RISCVVType::decodeVLMUL (LMUL);
322
+ return Fractional || LMul == 1 ;
323
+ }
324
+
304
325
// / Return true if moving from CurVType to NewVType is
305
326
// / indistinguishable from the perspective of an instruction (or set
306
327
// / of instructions) which use only the Used subfields and properties.
@@ -324,9 +345,18 @@ static bool areCompatibleVTYPEs(uint64_t CurVType, uint64_t NewVType,
324
345
break ;
325
346
}
326
347
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
+ }
330
360
331
361
if (Used.SEWLMULRatio ) {
332
362
auto Ratio1 = RISCVVType::getSEWLMULRatio (RISCVVType::getSEW (CurVType),
@@ -382,7 +412,7 @@ DemandedFields getDemanded(const MachineInstr &MI, const RISCVSubtarget *ST) {
382
412
// in the opcode. This is asserted when constructing the VSETVLIInfo.
383
413
if (getEEWForLoadStore (MI)) {
384
414
Res.SEW = DemandedFields::SEWNone;
385
- Res.LMUL = false ;
415
+ Res.LMUL = DemandedFields::LMULNone ;
386
416
}
387
417
388
418
// Store instructions don't use the policy fields.
@@ -397,12 +427,12 @@ DemandedFields getDemanded(const MachineInstr &MI, const RISCVSubtarget *ST) {
397
427
// * The policy bits can probably be ignored..
398
428
if (isMaskRegOp (MI)) {
399
429
Res.SEW = DemandedFields::SEWNone;
400
- Res.LMUL = false ;
430
+ Res.LMUL = DemandedFields::LMULNone ;
401
431
}
402
432
403
433
// For vmv.s.x and vfmv.s.f, there are only two behaviors, VL = 0 and VL > 0.
404
434
if (isScalarInsertInstr (MI)) {
405
- Res.LMUL = false ;
435
+ Res.LMUL = DemandedFields::LMULNone ;
406
436
Res.SEWLMULRatio = false ;
407
437
Res.VLAny = false ;
408
438
// 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) {
423
453
// vmv.x.s, and vmv.f.s are unconditional and ignore everything except SEW.
424
454
if (isScalarExtractInstr (MI)) {
425
455
assert (!RISCVII::hasVLOp (TSFlags));
426
- Res.LMUL = false ;
456
+ Res.LMUL = DemandedFields::LMULNone ;
427
457
Res.SEWLMULRatio = false ;
428
458
Res.TailPolicy = false ;
429
459
Res.MaskPolicy = false ;
@@ -1107,11 +1137,6 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
1107
1137
LIS->getMBBStartIdx (&MBB), LIS->getInstructionIndex (*MI).getRegSlot ());
1108
1138
}
1109
1139
1110
- static bool isLMUL1OrSmaller (RISCVII::VLMUL LMUL) {
1111
- auto [LMul, Fractional] = RISCVVType::decodeVLMUL (LMUL);
1112
- return Fractional || LMul == 1 ;
1113
- }
1114
-
1115
1140
// / Return true if a VSETVLI is required to transition from CurInfo to Require
1116
1141
// / before MI.
1117
1142
bool RISCVInsertVSETVLI::needVSETVLI (const MachineInstr &MI,
@@ -1133,10 +1158,10 @@ bool RISCVInsertVSETVLI::needVSETVLI(const MachineInstr &MI,
1133
1158
// * The LMUL1 restriction is for machines whose latency may depend on VL.
1134
1159
// * As above, this is only legal for tail "undefined" not "agnostic".
1135
1160
if (isVSlideInstr (MI) && Require.hasAVLImm () && Require.getAVLImm () == 1 &&
1136
- isLMUL1OrSmaller (CurInfo. getVLMUL ()) && hasUndefinedMergeOp (MI)) {
1161
+ hasUndefinedMergeOp (MI)) {
1137
1162
Used.VLAny = false ;
1138
1163
Used.VLZeroness = true ;
1139
- Used.LMUL = false ;
1164
+ Used.LMUL = DemandedFields::LMULLessThanOrEqualToM1 ;
1140
1165
Used.TailPolicy = false ;
1141
1166
}
1142
1167
@@ -1146,9 +1171,8 @@ bool RISCVInsertVSETVLI::needVSETVLI(const MachineInstr &MI,
1146
1171
// Since a splat is non-constant time in LMUL, we do need to be careful to not
1147
1172
// increase the number of active vector registers (unlike for vmv.s.x.)
1148
1173
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;
1152
1176
Used.SEWLMULRatio = false ;
1153
1177
Used.VLAny = false ;
1154
1178
if (isFloatScalarMoveOrScalarSplatInstr (MI) && !ST->hasVInstructionsF64 ())
@@ -1189,7 +1213,7 @@ static VSETVLIInfo adjustIncoming(VSETVLIInfo PrevInfo, VSETVLIInfo NewInfo,
1189
1213
if (auto NewVLMul = RISCVVType::getSameRatioLMUL (
1190
1214
PrevInfo.getSEW (), PrevInfo.getVLMUL (), Info.getSEW ()))
1191
1215
Info.setVLMul (*NewVLMul);
1192
- Demanded.LMUL = true ;
1216
+ Demanded.LMUL = DemandedFields::LMULEqual ;
1193
1217
}
1194
1218
1195
1219
return Info;
0 commit comments