diff options
| author | Evan Cheng <evan.cheng@apple.com> | 2009-06-03 09:00:27 +0000 |
|---|---|---|
| committer | Evan Cheng <evan.cheng@apple.com> | 2009-06-03 09:00:27 +0000 |
| commit | 2c48fe6757284e363248ea725ceedca8dd7ee272 (patch) | |
| tree | 6d79a7b7cf4ae2b9fc4ad9cac053d997eb9f2cad /lib/CodeGen/VirtRegRewriter.cpp | |
| parent | 70fd60bd57250799672378fa2f7c5e804cb3d98d (diff) | |
Fix for PR4225: When rewriter reuse a value in a physical register , it clear the register kill operand marker and its kill ops information. However, the cleared operand may be a def of a super-register. Clear the kill ops info for the super-register's sub-registers as well.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72758 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/VirtRegRewriter.cpp')
| -rw-r--r-- | lib/CodeGen/VirtRegRewriter.cpp | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/lib/CodeGen/VirtRegRewriter.cpp b/lib/CodeGen/VirtRegRewriter.cpp index b4c8bc1297..c31f622e24 100644 --- a/lib/CodeGen/VirtRegRewriter.cpp +++ b/lib/CodeGen/VirtRegRewriter.cpp @@ -411,9 +411,11 @@ static void InvalidateKill(unsigned Reg, std::vector<MachineOperand*> &KillOps) { if (RegKills[Reg]) { KillOps[Reg]->setIsKill(false); - KillOps[Reg] = NULL; - RegKills.reset(Reg); - for (const unsigned *SR = TRI->getSubRegisters(Reg); *SR; ++SR) { + // KillOps[Reg] might be a def of a super-register. + unsigned KReg = KillOps[Reg]->getReg(); + KillOps[KReg] = NULL; + RegKills.reset(KReg); + for (const unsigned *SR = TRI->getSubRegisters(KReg); *SR; ++SR) { if (RegKills[*SR]) { KillOps[*SR]->setIsKill(false); KillOps[*SR] = NULL; @@ -516,8 +518,18 @@ static void UpdateKills(MachineInstr &MI, const TargetRegisterInfo* TRI, // That can't be right. Register is killed but not re-defined and it's // being reused. Let's fix that. KillOps[Reg]->setIsKill(false); - KillOps[Reg] = NULL; - RegKills.reset(Reg); + // KillOps[Reg] might be a def of a super-register. + unsigned KReg = KillOps[Reg]->getReg(); + KillOps[KReg] = NULL; + RegKills.reset(KReg); + + // Must be a def of a super-register. Its other sub-regsters are no + // longer killed as well. + for (const unsigned *SR = TRI->getSubRegisters(KReg); *SR; ++SR) { + KillOps[*SR] = NULL; + RegKills.reset(*SR); + } + if (!MI.isRegTiedToDefOperand(i)) // Unless it's a two-address operand, this is the new kill. MO.setIsKill(); @@ -1090,6 +1102,8 @@ private: VRM.RemoveMachineInstrFromMaps(&NextMI); MBB.erase(&NextMI); ++NumModRefUnfold; + if (NextMII == MBB.end()) + break; } while (FoldsStackSlotModRef(*NextMII, SS, PhysReg, TII, TRI, VRM)); // Store the value back into SS. |
