Index: lib/CodeGen/MachineVerifier.cpp =================================================================== --- lib/CodeGen/MachineVerifier.cpp +++ lib/CodeGen/MachineVerifier.cpp @@ -49,6 +49,7 @@ #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/PseudoSourceValue.h" +#include "llvm/CodeGen/RegisterUsageInfo.h" #include "llvm/CodeGen/SlotIndexes.h" #include "llvm/CodeGen/StackMaps.h" #include "llvm/CodeGen/TargetInstrInfo.h" @@ -95,6 +96,7 @@ const TargetInstrInfo *TII; const TargetRegisterInfo *TRI; const MachineRegisterInfo *MRI; + PhysicalRegisterUsageInfo *PRUI; unsigned foundErrors; @@ -282,6 +284,7 @@ void verifySlotIndexes() const; void verifyProperties(const MachineFunction &MF); + void verifyUsedPhysRegs(const MachineFunction &MF); }; struct MachineVerifierPass : public MachineFunctionPass { @@ -350,6 +353,40 @@ report("Function has NoVRegs property but there are VReg operands", &MF); } +static bool regIsInSet(const uint32_t *RegMask, unsigned PhysReg) { + return !MachineOperand::clobbersPhysReg(RegMask, PhysReg); +} + +void MachineVerifier::verifyUsedPhysRegs(const MachineFunction &MF) { + // PhysicalRegisterUsageInfo becomes available with interprocedural + // register allocation. + if (!PRUI) + return; + const Function &F = MF.getFunction(); + const auto *PreservedRegs = PRUI->getRegUsageInfo(&F); + if (!PreservedRegs) + return; + const uint32_t *CallPreservedMask = + TRI->getCallPreservedMask(MF, F.getCallingConv()); + if (!CallPreservedMask) + return; + + for (unsigned PReg = 1, PRegE = TRI->getNumRegs(); PReg < PRegE; ++PReg) { + // Any register defined by an instruction that is not preserved across a + // call according to the calling convention should result in all aliases + // excluded from the function mask of preserved registers. + if (MRI->def_empty(PReg) || regIsInSet(CallPreservedMask, PReg)) + continue; + for (MCRegAliasIterator AI(PReg, TRI, true); AI.isValid(); ++AI) + if (regIsInSet(&(*PreservedRegs)[0], *AI)) { + std::string Msg = "Defined register (alias) not in RegUsageInfo: " + + std::string(TRI->getName(*AI)); + const MachineOperand &DefMO = *MRI->def_begin(PReg); + report(Msg.c_str(), DefMO.getParent()); + } + } +} + unsigned MachineVerifier::verify(MachineFunction &MF) { foundErrors = 0; @@ -372,6 +409,7 @@ LiveInts = nullptr; LiveStks = nullptr; Indexes = nullptr; + PRUI = nullptr; if (PASS) { LiveInts = PASS->getAnalysisIfAvailable(); // We don't want to verify LiveVariables if LiveIntervals is available. @@ -379,12 +417,15 @@ LiveVars = PASS->getAnalysisIfAvailable(); LiveStks = PASS->getAnalysisIfAvailable(); Indexes = PASS->getAnalysisIfAvailable(); + PRUI = PASS->getAnalysisIfAvailable(); } verifySlotIndexes(); verifyProperties(MF); + verifyUsedPhysRegs(MF); + visitMachineFunctionBefore(); for (MachineFunction::const_iterator MFI = MF.begin(), MFE = MF.end(); MFI!=MFE; ++MFI) {