diff options
author | Björn Pettersson <bjorn.a.pettersson@ericsson.com> | 2024-06-25 10:05:14 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-25 10:05:14 +0200 |
commit | 7f1a74429dfd62a410d4b51d2e75d3677429a51a (patch) | |
tree | caabfca423bdb39610388ce849b7d932aac27e30 /llvm/lib | |
parent | 01fb5290eb86f056e6ba8757011273bcb7f4f2ee (diff) | |
download | llvm-7f1a74429dfd62a410d4b51d2e75d3677429a51a.zip llvm-7f1a74429dfd62a410d4b51d2e75d3677429a51a.tar.gz llvm-7f1a74429dfd62a410d4b51d2e75d3677429a51a.tar.bz2 |
[TailDup][MachineSSAUpdater] Let RewriteUse insert a COPY when needed (#95553)
When running early-tailduplication we've seen problems with machine
verifier errors due to register class mismatches after doing the machine
SSA updates.
Typical scenario is that there is a PHI node and another instruction
that is using the same vreg:
%othervreg:otherclass = PHI %vreg:origclass, %bb
MInstr %vreg:origclass
but then after TailDuplicator::tailDuplicateAndUpdate we get
%othervreg:otherclass = PHI %vreg:origclass, %bb, ...
MInstr %othervreg:otherclass
Such rewrites are only valid if 'otherclass' is equal to (or a subclass
of) 'origclass'.
The solution here is based on adding a COPY instruction to make sure we
satisfy constraints given by 'MInstr' in the example. So if 'otherclass'
isn't equal to (or a subclass of) 'origclass' we insert a copy after the
PHI like this:
%othervreg:otherclass = PHI %vreg:origclass, %bb, ...
%newvreg:origclass = COPY %othervreg:otherclass
MInstr %newvreg:origclass
A special case is when it is possible to constrain the register class
instead of inserting a COPY. We currently prefer to constrain the
register class instead of inserting a COPY, even if it is a bit unclear
if that always is better (considering register pressure for the
constrained class etc.).
Fixes: https://github.com/llvm/llvm-project/issues/62712
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/MachineSSAUpdater.cpp | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/MachineSSAUpdater.cpp b/llvm/lib/CodeGen/MachineSSAUpdater.cpp index 8d6ea9c..5b21c56 100644 --- a/llvm/lib/CodeGen/MachineSSAUpdater.cpp +++ b/llvm/lib/CodeGen/MachineSSAUpdater.cpp @@ -209,7 +209,7 @@ Register MachineSSAUpdater::GetValueInMiddleOfBlock(MachineBasicBlock *BB, // If the client wants to know about all new instructions, tell it. if (InsertedPHIs) InsertedPHIs->push_back(InsertedPHI); - LLVM_DEBUG(dbgs() << " Inserted PHI: " << *InsertedPHI << "\n"); + LLVM_DEBUG(dbgs() << " Inserted PHI: " << *InsertedPHI); return InsertedPHI.getReg(0); } @@ -236,6 +236,22 @@ void MachineSSAUpdater::RewriteUse(MachineOperand &U) { NewVR = GetValueInMiddleOfBlock(UseMI->getParent()); } + // Insert a COPY if needed to satisfy register class constraints for the using + // MO. Or, if possible, just constrain the class for NewVR to avoid the need + // for a COPY. + if (NewVR) { + const TargetRegisterClass *UseRC = + dyn_cast_or_null<const TargetRegisterClass *>(RegAttrs.RCOrRB); + if (UseRC && !MRI->constrainRegClass(NewVR, UseRC)) { + MachineBasicBlock *UseBB = UseMI->getParent(); + MachineInstr *InsertedCopy = + InsertNewDef(TargetOpcode::COPY, UseBB, UseBB->getFirstNonPHI(), + RegAttrs, MRI, TII) + .addReg(NewVR); + NewVR = InsertedCopy->getOperand(0).getReg(); + LLVM_DEBUG(dbgs() << " Inserted COPY: " << *InsertedCopy); + } + } U.setReg(NewVR); } |