diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:04 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:11 +0000 |
| commit | e3b557809604d036af6e00c60f012c2025b59a5e (patch) | |
| tree | 8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/CodeGen/TwoAddressInstructionPass.cpp | |
| parent | 08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff) | |
Diffstat (limited to 'llvm/lib/CodeGen/TwoAddressInstructionPass.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/TwoAddressInstructionPass.cpp | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp index 17fe819fa900..8cb3667aea28 100644 --- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -1657,13 +1657,50 @@ bool TwoAddressInstructionPass::processStatepoint( if (RegA == RegB) continue; + // CodeGenPrepare can sink pointer compare past statepoint, which + // breaks assumption that statepoint kills tied-use register when + // in SSA form (see note in IR/SafepointIRVerifier.cpp). Fall back + // to generic tied register handling to avoid assertion failures. + // TODO: Recompute LIS/LV information for new range here. + if (LIS) { + const auto &UseLI = LIS->getInterval(RegB); + const auto &DefLI = LIS->getInterval(RegA); + if (DefLI.overlaps(UseLI)) { + LLVM_DEBUG(dbgs() << "LIS: " << printReg(RegB, TRI, 0) + << " UseLI overlaps with DefLI\n"); + NeedCopy = true; + continue; + } + } else if (LV && LV->getVarInfo(RegB).findKill(MI->getParent()) != MI) { + // Note that MachineOperand::isKill does not work here, because it + // is set only on first register use in instruction and for statepoint + // tied-use register will usually be found in preceeding deopt bundle. + LLVM_DEBUG(dbgs() << "LV: " << printReg(RegB, TRI, 0) + << " not killed by statepoint\n"); + NeedCopy = true; + continue; + } + + if (!MRI->constrainRegClass(RegB, MRI->getRegClass(RegA))) { + LLVM_DEBUG(dbgs() << "MRI: couldn't constrain" << printReg(RegB, TRI, 0) + << " to register class of " << printReg(RegA, TRI, 0) + << '\n'); + NeedCopy = true; + continue; + } MRI->replaceRegWith(RegA, RegB); if (LIS) { VNInfo::Allocator &A = LIS->getVNInfoAllocator(); LiveInterval &LI = LIS->getInterval(RegB); - for (auto &S : LIS->getInterval(RegA)) { - VNInfo *VNI = LI.getNextValue(S.start, A); + LiveInterval &Other = LIS->getInterval(RegA); + SmallVector<VNInfo *> NewVNIs; + for (const VNInfo *VNI : Other.valnos) { + assert(VNI->id == NewVNIs.size() && "assumed"); + NewVNIs.push_back(LI.createValueCopy(VNI, A)); + } + for (auto &S : Other) { + VNInfo *VNI = NewVNIs[S.valno->id]; LiveRange::Segment NewSeg(S.start, S.end, VNI); LI.addSegment(NewSeg); } @@ -1676,6 +1713,7 @@ bool TwoAddressInstructionPass::processStatepoint( LiveVariables::VarInfo &SrcInfo = LV->getVarInfo(RegB); LiveVariables::VarInfo &DstInfo = LV->getVarInfo(RegA); SrcInfo.AliveBlocks |= DstInfo.AliveBlocks; + DstInfo.AliveBlocks.clear(); for (auto *KillMI : DstInfo.Kills) LV->addVirtualRegisterKilled(RegB, *KillMI, false); } @@ -1857,11 +1895,6 @@ void TwoAddressInstructionPass:: eliminateRegSequence(MachineBasicBlock::iterator &MBBI) { MachineInstr &MI = *MBBI; Register DstReg = MI.getOperand(0).getReg(); - if (MI.getOperand(0).getSubReg() || DstReg.isPhysical() || - !(MI.getNumOperands() & 1)) { - LLVM_DEBUG(dbgs() << "Illegal REG_SEQUENCE instruction:" << MI); - llvm_unreachable(nullptr); - } SmallVector<Register, 4> OrigRegs; if (LIS) { |
