@@ -40,6 +40,12 @@ using namespace llvm;
4040STATISTIC (NumInsertedVSETVL, " Number of VSETVL inst inserted" );
4141STATISTIC (NumCoalescedVSETVL, " Number of VSETVL inst coalesced" );
4242
43+ static cl::opt<bool > EnsureWholeVectorRegisterMoveValidVTYPE (
44+ DEBUG_TYPE " -whole-vector-register-move-valid-vtype" , cl::Hidden,
45+ cl::desc (" Insert vsetvlis before vmvNr.vs to ensure vtype is valid and "
46+ " vill is cleared" ),
47+ cl::init(true ));
48+
4349namespace {
4450
4551// / Given a virtual register \p Reg, return the corresponding VNInfo for it.
@@ -195,6 +201,14 @@ static bool hasUndefinedPassthru(const MachineInstr &MI) {
195201 return UseMO.getReg () == RISCV::NoRegister || UseMO.isUndef ();
196202}
197203
204+ // / Return true if \p MI is a copy that will be lowered to one or more vmvNr.vs.
205+ static bool isVectorCopy (const TargetRegisterInfo *TRI,
206+ const MachineInstr &MI) {
207+ return MI.isCopy () && MI.getOperand (0 ).getReg ().isPhysical () &&
208+ RISCVRegisterInfo::isRVVRegClass (
209+ TRI->getMinimalPhysRegClass (MI.getOperand (0 ).getReg ()));
210+ }
211+
198212// / Which subfields of VL or VTYPE have values we need to preserve?
199213struct DemandedFields {
200214 // Some unknown property of VL is used. If demanded, must preserve entire
@@ -221,10 +235,13 @@ struct DemandedFields {
221235 bool SEWLMULRatio = false ;
222236 bool TailPolicy = false ;
223237 bool MaskPolicy = false ;
238+ // If this is true, we demand that VTYPE is set to some legal state, i.e. that
239+ // vill is unset.
240+ bool VILL = false ;
224241
225242 // Return true if any part of VTYPE was used
226243 bool usedVTYPE () const {
227- return SEW || LMUL || SEWLMULRatio || TailPolicy || MaskPolicy;
244+ return SEW || LMUL || SEWLMULRatio || TailPolicy || MaskPolicy || VILL ;
228245 }
229246
230247 // Return true if any property of VL was used
@@ -239,6 +256,7 @@ struct DemandedFields {
239256 SEWLMULRatio = true ;
240257 TailPolicy = true ;
241258 MaskPolicy = true ;
259+ VILL = true ;
242260 }
243261
244262 // Mark all VL properties as demanded
@@ -263,6 +281,7 @@ struct DemandedFields {
263281 SEWLMULRatio |= B.SEWLMULRatio ;
264282 TailPolicy |= B.TailPolicy ;
265283 MaskPolicy |= B.MaskPolicy ;
284+ VILL |= B.VILL ;
266285 }
267286
268287#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
@@ -308,7 +327,8 @@ struct DemandedFields {
308327 OS << " , " ;
309328 OS << " SEWLMULRatio=" << SEWLMULRatio << " , " ;
310329 OS << " TailPolicy=" << TailPolicy << " , " ;
311- OS << " MaskPolicy=" << MaskPolicy;
330+ OS << " MaskPolicy=" << MaskPolicy << " , " ;
331+ OS << " VILL=" << VILL;
312332 OS << " }" ;
313333 }
314334#endif
@@ -503,6 +523,21 @@ DemandedFields getDemanded(const MachineInstr &MI, const RISCVSubtarget *ST) {
503523 }
504524 }
505525
526+ // In §32.16.6, whole vector register moves have a dependency on SEW. At the
527+ // MIR level though we don't encode the element type, and it gives the same
528+ // result whatever the SEW may be.
529+ //
530+ // However it does need valid SEW, i.e. vill must be cleared. The entry to a
531+ // function, calls and inline assembly may all set it, so make sure we clear
532+ // it for whole register copies. Do this by leaving VILL demanded.
533+ if (isVectorCopy (ST->getRegisterInfo (), MI)) {
534+ Res.LMUL = DemandedFields::LMULNone;
535+ Res.SEW = DemandedFields::SEWNone;
536+ Res.SEWLMULRatio = false ;
537+ Res.TailPolicy = false ;
538+ Res.MaskPolicy = false ;
539+ }
540+
506541 return Res;
507542}
508543
@@ -1208,6 +1243,18 @@ static VSETVLIInfo adjustIncoming(VSETVLIInfo PrevInfo, VSETVLIInfo NewInfo,
12081243// legal for MI, but may not be the state requested by MI.
12091244void RISCVInsertVSETVLI::transferBefore (VSETVLIInfo &Info,
12101245 const MachineInstr &MI) const {
1246+ if (isVectorCopy (ST->getRegisterInfo (), MI) &&
1247+ (Info.isUnknown () || !Info.isValid () || Info.hasSEWLMULRatioOnly ())) {
1248+ // Use an arbitrary but valid AVL and VTYPE so vill will be cleared. It may
1249+ // be coalesced into another vsetvli since we won't demand any fields.
1250+ VSETVLIInfo NewInfo; // Need a new VSETVLIInfo to clear SEWLMULRatioOnly
1251+ NewInfo.setAVLImm (1 );
1252+ NewInfo.setVTYPE (RISCVII::VLMUL::LMUL_1, /* sew*/ 8 , /* ta*/ true ,
1253+ /* ma*/ true );
1254+ Info = NewInfo;
1255+ return ;
1256+ }
1257+
12111258 if (!RISCVII::hasSEWOp (MI.getDesc ().TSFlags ))
12121259 return ;
12131260
@@ -1296,7 +1343,8 @@ bool RISCVInsertVSETVLI::computeVLVTYPEChanges(const MachineBasicBlock &MBB,
12961343 for (const MachineInstr &MI : MBB) {
12971344 transferBefore (Info, MI);
12981345
1299- if (isVectorConfigInstr (MI) || RISCVII::hasSEWOp (MI.getDesc ().TSFlags ))
1346+ if (isVectorConfigInstr (MI) || RISCVII::hasSEWOp (MI.getDesc ().TSFlags ) ||
1347+ isVectorCopy (ST->getRegisterInfo (), MI))
13001348 HadVectorOp = true ;
13011349
13021350 transferAfter (Info, MI);
@@ -1426,6 +1474,16 @@ void RISCVInsertVSETVLI::emitVSETVLIs(MachineBasicBlock &MBB) {
14261474 PrefixTransparent = false ;
14271475 }
14281476
1477+ if (EnsureWholeVectorRegisterMoveValidVTYPE &&
1478+ isVectorCopy (ST->getRegisterInfo (), MI)) {
1479+ if (!PrevInfo.isCompatible (DemandedFields::all (), CurInfo, LIS)) {
1480+ insertVSETVLI (MBB, MI, MI.getDebugLoc (), CurInfo, PrevInfo);
1481+ PrefixTransparent = false ;
1482+ }
1483+ MI.addOperand (MachineOperand::CreateReg (RISCV::VTYPE, /* isDef*/ false ,
1484+ /* isImp*/ true ));
1485+ }
1486+
14291487 uint64_t TSFlags = MI.getDesc ().TSFlags ;
14301488 if (RISCVII::hasSEWOp (TSFlags)) {
14311489 if (!PrevInfo.isCompatible (DemandedFields::all (), CurInfo, LIS)) {
0 commit comments