-
Notifications
You must be signed in to change notification settings - Fork 15.3k
RegAllocFast: Fix verifier errors after assigning to reserved registers #128155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -206,6 +206,7 @@ class RegAllocFastImpl { | |
| bool Error = false; ///< Could not allocate. | ||
|
|
||
| explicit LiveReg(Register VirtReg) : VirtReg(VirtReg) {} | ||
| explicit LiveReg() {} | ||
|
|
||
| unsigned getSparseSetIndex() const { return VirtReg.virtRegIndex(); } | ||
| }; | ||
|
|
@@ -216,7 +217,7 @@ class RegAllocFastImpl { | |
| LiveRegMap LiveVirtRegs; | ||
|
|
||
| /// Stores assigned virtual registers present in the bundle MI. | ||
| DenseMap<Register, MCPhysReg> BundleVirtRegsMap; | ||
| DenseMap<Register, LiveReg> BundleVirtRegsMap; | ||
|
|
||
| DenseMap<unsigned, SmallVector<MachineOperand *, 2>> LiveDbgValueMap; | ||
| /// List of DBG_VALUE that we encountered without the vreg being assigned | ||
|
|
@@ -374,7 +375,8 @@ class RegAllocFastImpl { | |
| SmallSet<Register, 2> &PrologLiveIns) const; | ||
|
|
||
| void reloadAtBegin(MachineBasicBlock &MBB); | ||
| bool setPhysReg(MachineInstr &MI, MachineOperand &MO, MCPhysReg PhysReg); | ||
| bool setPhysReg(MachineInstr &MI, MachineOperand &MO, | ||
| const LiveReg &Assignment); | ||
|
|
||
| Register traceCopies(Register VirtReg) const; | ||
| Register traceCopyChain(Register Reg) const; | ||
|
|
@@ -1005,7 +1007,8 @@ void RegAllocFastImpl::allocVirtRegUndef(MachineOperand &MO) { | |
| MO.setSubReg(0); | ||
| } | ||
| MO.setReg(PhysReg); | ||
| MO.setIsRenamable(true); | ||
| if (!LRI->Error) | ||
| MO.setIsRenamable(true); | ||
| } | ||
|
|
||
| /// Variation of defineVirtReg() with special handling for livethrough regs | ||
|
|
@@ -1109,10 +1112,10 @@ bool RegAllocFastImpl::defineVirtReg(MachineInstr &MI, unsigned OpNum, | |
| LRI->Reloaded = false; | ||
| } | ||
| if (MI.getOpcode() == TargetOpcode::BUNDLE) { | ||
| BundleVirtRegsMap[VirtReg] = PhysReg; | ||
| BundleVirtRegsMap[VirtReg] = *LRI; | ||
| } | ||
| markRegUsedInInstr(PhysReg); | ||
| return setPhysReg(MI, MO, PhysReg); | ||
| return setPhysReg(MI, MO, *LRI); | ||
| } | ||
|
|
||
| /// Allocates a register for a VirtReg use. | ||
|
|
@@ -1158,10 +1161,10 @@ bool RegAllocFastImpl::useVirtReg(MachineInstr &MI, MachineOperand &MO, | |
| LRI->LastUse = &MI; | ||
|
|
||
| if (MI.getOpcode() == TargetOpcode::BUNDLE) { | ||
| BundleVirtRegsMap[VirtReg] = LRI->PhysReg; | ||
| BundleVirtRegsMap[VirtReg] = *LRI; | ||
| } | ||
| markRegUsedInInstr(LRI->PhysReg); | ||
| return setPhysReg(MI, MO, LRI->PhysReg); | ||
| return setPhysReg(MI, MO, *LRI); | ||
| } | ||
|
|
||
| /// Query a physical register to use as a filler in contexts where the | ||
|
|
@@ -1215,16 +1218,30 @@ MCPhysReg RegAllocFastImpl::getErrorAssignment(const LiveReg &LR, | |
| /// Changes operand OpNum in MI the refer the PhysReg, considering subregs. | ||
| /// \return true if MI's MachineOperands were re-arranged/invalidated. | ||
| bool RegAllocFastImpl::setPhysReg(MachineInstr &MI, MachineOperand &MO, | ||
| MCPhysReg PhysReg) { | ||
| const LiveReg &Assignment) { | ||
| MCPhysReg PhysReg = Assignment.PhysReg; | ||
|
|
||
| assert(PhysReg); | ||
|
|
||
| if (LLVM_UNLIKELY(Assignment.Error)) { | ||
| if (MO.isUse()) | ||
| MO.setIsUndef(true); | ||
| } | ||
|
|
||
| if (!MO.getSubReg()) { | ||
| MO.setReg(PhysReg); | ||
| MO.setIsRenamable(true); | ||
| MO.setIsRenamable(!Assignment.Error); | ||
| return false; | ||
| } | ||
|
|
||
| assert(PhysReg); | ||
|
||
|
|
||
| // Handle subregister index. | ||
| MO.setReg(PhysReg ? TRI->getSubReg(PhysReg, MO.getSubReg()) : MCRegister()); | ||
| MO.setIsRenamable(true); | ||
|
|
||
| if (PhysReg) | ||
| MO.setIsRenamable(!Assignment.Error); | ||
|
|
||
| // Note: We leave the subreg number around a little longer in case of defs. | ||
| // This is so that the register freeing logic in allocateInstruction can still | ||
| // recognize this as subregister defs. The code there will clear the number. | ||
|
|
@@ -1706,7 +1723,7 @@ void RegAllocFastImpl::handleDebugValue(MachineInstr &MI) { | |
| if (LRI != LiveVirtRegs.end() && LRI->PhysReg) { | ||
| // Update every use of Reg within MI. | ||
| for (auto &RegMO : DbgOps) | ||
| setPhysReg(MI, *RegMO, LRI->PhysReg); | ||
| setPhysReg(MI, *RegMO, *LRI); | ||
| } else { | ||
| DanglingDbgValues[Reg].push_back(&MI); | ||
| } | ||
|
|
@@ -1729,8 +1746,7 @@ void RegAllocFastImpl::handleBundle(MachineInstr &MI) { | |
| if (!Reg.isVirtual() || !shouldAllocateRegister(Reg)) | ||
| continue; | ||
|
|
||
| DenseMap<Register, MCPhysReg>::iterator DI; | ||
| DI = BundleVirtRegsMap.find(Reg); | ||
| DenseMap<Register, LiveReg>::iterator DI = BundleVirtRegsMap.find(Reg); | ||
| assert(DI != BundleVirtRegsMap.end() && "Unassigned virtual register"); | ||
|
|
||
| setPhysReg(MI, MO, DI->second); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -598,6 +598,9 @@ void VirtRegRewriter::rewrite() { | |
| SmallVector<Register, 8> SuperDefs; | ||
| SmallVector<Register, 8> SuperKills; | ||
|
|
||
| const bool IsValidAlloc = !MF->getProperties().hasProperty( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: You can avoid the double negation if the variable name is changed to
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This keeps the negation out of the loop |
||
| MachineFunctionProperties::Property::FailedRegAlloc); | ||
|
|
||
| for (MachineFunction::iterator MBBI = MF->begin(), MBBE = MF->end(); | ||
| MBBI != MBBE; ++MBBI) { | ||
| LLVM_DEBUG(MBBI->print(dbgs(), Indexes)); | ||
|
|
@@ -617,9 +620,7 @@ void VirtRegRewriter::rewrite() { | |
| assert(Register(PhysReg).isPhysical()); | ||
|
|
||
| RewriteRegs.insert(PhysReg); | ||
| assert((!MRI->isReserved(PhysReg) || | ||
| MF->getProperties().hasProperty( | ||
| MachineFunctionProperties::Property::FailedRegAlloc)) && | ||
| assert((!MRI->isReserved(PhysReg) || !IsValidAlloc) && | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unrelated to this PR - should insert a separate assertion for FailedRegalloc with an appropriate failure message. |
||
| "Reserved register assignment"); | ||
|
|
||
| // Preserve semantics of sub-register operands. | ||
|
|
@@ -695,7 +696,14 @@ void VirtRegRewriter::rewrite() { | |
| // Rewrite. Note we could have used MachineOperand::substPhysReg(), but | ||
| // we need the inlining here. | ||
| MO.setReg(PhysReg); | ||
| MO.setIsRenamable(true); | ||
|
|
||
| // Defend against generating invalid flags in allocation failure | ||
| // scenarios. We have have assigned a register which was undefined, or a | ||
| // reserved register which cannot be renamable. | ||
| if (LLVM_LIKELY(IsValidAlloc)) | ||
| MO.setIsRenamable(true); | ||
| else if (MO.isUse()) | ||
| MO.setIsUndef(true); | ||
| } | ||
|
|
||
| // Add any missing super-register kills after rewriting the whole | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this assertion be here, given that !PhysReg is handled below?