Index: lib/CodeGen/MachineVerifier.cpp =================================================================== --- lib/CodeGen/MachineVerifier.cpp +++ lib/CodeGen/MachineVerifier.cpp @@ -86,7 +86,9 @@ BitVector regsReserved; RegSet regsLive; RegVector regsDefined, regsDead, regsKilled; + SmallVector expectedLiveOuts; RegMaskVector regMasks; + BitVector PristineRegs; SlotIndex lastIndex; @@ -221,6 +223,7 @@ void report_context(SlotIndex Pos) const; void report_context_liverange(const LiveRange &LR) const; void report_context_lanemask(LaneBitmask LaneMask) const; + void report_context_reg(unsigned Reg) const; void report_context_vreg(unsigned VReg) const; void report_context_vreg_regunit(unsigned VRegOrRegUnit) const; @@ -497,6 +500,10 @@ errs() << "- liverange: " << LR << '\n'; } +void MachineVerifier::report_context_reg(unsigned Reg) const { + errs() << "- register: " << PrintReg(Reg, TRI) << '\n'; +} + void MachineVerifier::report_context_vreg(unsigned VReg) const { errs() << "- v. register: " << PrintReg(VReg, TRI) << '\n'; } @@ -551,6 +558,9 @@ if (!MF->empty()) verifyStackFrame(); + + const MachineFrameInfo &MFI = MF->getFrameInfo(); + PristineRegs = MFI.getPristineRegs(*MF); } // Does iterator point to a and b as the first two elements? @@ -745,19 +755,27 @@ regsLive.clear(); if (MRI->tracksLiveness()) { for (const auto &LI : MBB->liveins()) { - if (!TargetRegisterInfo::isPhysicalRegister(LI.PhysReg)) { + unsigned Reg = LI.PhysReg; + if (!TargetRegisterInfo::isPhysicalRegister(Reg)) { report("MBB live-in list contains non-physical register", MBB); + report_context_reg(Reg); continue; } + if (MRI->reservedRegsFrozen() && MRI->isReserved(LI.PhysReg)) { + report("MBB live-in list contains reserved register", MBB); + report_context_reg(Reg); + } + if (PristineRegs.test(LI.PhysReg)) { + report("MBB live-in list contains pristine register", MBB); + report_context_reg(Reg); + } for (MCSubRegIterator SubRegs(LI.PhysReg, TRI, /*IncludeSelf=*/true); SubRegs.isValid(); ++SubRegs) regsLive.insert(*SubRegs); } } - const MachineFrameInfo &MFI = MF->getFrameInfo(); - BitVector PR = MFI.getPristineRegs(*MF); - for (unsigned I : PR.set_bits()) { + for (unsigned I : PristineRegs.set_bits()) { for (MCSubRegIterator SubRegs(I, TRI, /*IncludeSelf=*/true); SubRegs.isValid(); ++SubRegs) regsLive.insert(*SubRegs); @@ -1439,7 +1457,6 @@ void MachineVerifier::visitMachineBasicBlockAfter(const MachineBasicBlock *MBB) { MBBInfoMap[MBB].regsLiveOut = regsLive; - regsLive.clear(); if (Indexes) { SlotIndex stop = Indexes->getMBBEndIdx(MBB); @@ -1450,6 +1467,66 @@ } lastIndex = stop; } + + if (MRI->tracksLiveness()) { + expectedLiveOuts.clear(); + if (MBB->isReturnBlock() && !MBB->back().isCall()) { + // Note: We excluded tailcalls here as we do not care about CSR after the + // call. TODO: We should check CSRs before the tailcall instead. + + const MachineFrameInfo &MFI = MF->getFrameInfo(); + if (MFI.isCalleeSavedInfoValid()) { + for (const MCPhysReg *CSR = MRI->getCalleeSavedRegs(); CSR && *CSR; + ++CSR) { + if (MRI->isReserved(*CSR)) + continue; + bool Pristine = true; + for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) { + unsigned SavedReg = Info.getReg(); + if (TRI->isSuperRegisterEq(*CSR, SavedReg)) { + Pristine = false; + break; + } + } + if (!Pristine) + expectedLiveOuts.push_back(*CSR); + } + } + } else { + for (const MachineBasicBlock *Succ : MBB->successors()) { + if (Succ->isEHPad()) { + // Don't add any expected regs. As EHPads can have live-ins that are the + // result of the unwind/personality function that are not live-out of + // the predecessor. + break; + } + for (const auto &LI : Succ->liveins()) { + unsigned Reg = LI.PhysReg; + if (TargetRegisterInfo::isPhysicalRegister(Reg) && + !MRI->isReserved(Reg)) + expectedLiveOuts.push_back(Reg); + } + } + } + + for (MCPhysReg Reg : expectedLiveOuts) { + /* At least any of the subregisters should be live. */ + bool IsLive = false; + for (MCSubRegIterator SR(Reg, TRI, true); SR.isValid(); ++SR) { + if (regsLive.count(*SR)) { + IsLive = true; + break; + } + } + if (!IsLive) { + report("Expected register to be live at end of MBB", MBB); + report_context_reg(Reg); + } + } + expectedLiveOuts.clear(); + } + + regsLive.clear(); } // Calculate the largest possible vregsPassed sets. These are the registers that Index: test/CodeGen/AArch64/machine-copy-remove.mir =================================================================== --- test/CodeGen/AArch64/machine-copy-remove.mir +++ test/CodeGen/AArch64/machine-copy-remove.mir @@ -204,7 +204,7 @@ tracksRegLiveness: true body: | bb.0: - liveins: %x0, %x1 + liveins: %x0, %x1, %x2 %x1 = COPY %x0 CBNZX %x1, %bb.2 @@ -236,7 +236,7 @@ tracksRegLiveness: true body: | bb.0: - liveins: %x0, %x1 + liveins: %x0, %x1, %x2 CBNZX %x0, %bb.2 @@ -247,7 +247,7 @@ B %bb.3 bb.2: - liveins: %x1 + liveins: %x1, %x2 %x0 = LDRXui %x1, 0