https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/225176
>From 4bc5bfe173eb5d9747523ec2f16baacb762e76ad Mon Sep 17 00:00:00 2001 From: Matt Arsenault <[email protected]> Date: Tue, 8 Sep 2026 22:09:04 +0200 Subject: [PATCH] CodeGen: Remove LiveVariables use from TwoAddressInstructionPass Now that LiveIntervals is computed unconditionally before TwoAddressInstructions in the pipeline, the pass no longer needs LiveVariables. Co-authored-by: Claude (Claude-Opus-4.8) <[email protected]> --- .../lib/CodeGen/TwoAddressInstructionPass.cpp | 169 ++++-------------- .../CodeGen/Hexagon/two-addr-tied-subregs.mir | 14 +- llvm/test/CodeGen/SystemZ/twoaddr-kill.mir | 16 +- .../statepoint-cmp-sunk-past-statepoint.ll | 4 +- .../statepoint-vreg-unlimited-tied-opnds.ll | 36 ++-- .../X86/two-address-subreg-to-reg-kill.mir | 25 +-- llvm/test/CodeGen/X86/twoaddr-dbg-value.mir | 6 +- 7 files changed, 85 insertions(+), 185 deletions(-) diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp index 0d1ab23757f9f..62c87d7360e42 100644 --- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -34,7 +34,6 @@ #include "llvm/ADT/iterator_range.h" #include "llvm/CodeGen/LiveInterval.h" #include "llvm/CodeGen/LiveIntervals.h" -#include "llvm/CodeGen/LiveVariables.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunction.h" @@ -99,7 +98,6 @@ class TwoAddressInstructionImpl { const TargetRegisterInfo *TRI = nullptr; const InstrItineraryData *InstrItins = nullptr; MachineRegisterInfo *MRI = nullptr; - LiveVariables *LV = nullptr; LiveIntervals *LIS = nullptr; CodeGenOptLevel OptLevel = CodeGenOptLevel::None; @@ -218,8 +216,6 @@ class TwoAddressInstructionLegacyPass : public MachineFunctionPass { void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); - AU.addUsedIfAvailable<LiveVariablesWrapperPass>(); - AU.addPreserved<LiveVariablesWrapperPass>(); AU.addUsedIfAvailable<LiveIntervalsWrapperPass>(); AU.addPreserved<SlotIndexesWrapperPass>(); AU.addPreserved<LiveIntervalsWrapperPass>(); @@ -252,7 +248,6 @@ TwoAddressInstructionPass::run(MachineFunction &MF, if (LIS) PA.preserve<SlotIndexesAnalysis>(); - PA.preserve<LiveVariablesAnalysis>(); PA.preserve<LiveIntervalsAnalysis>(); PA.preserveSet<CFGAnalyses>(); return PA; @@ -271,8 +266,7 @@ TwoAddressInstructionImpl::TwoAddressInstructionImpl( : MF(&Func), TII(Func.getSubtarget().getInstrInfo()), TRI(Func.getSubtarget().getRegisterInfo()), InstrItins(Func.getSubtarget().getInstrItineraryData()), - MRI(&Func.getRegInfo()), - LV(MFAM.getCachedResult<LiveVariablesAnalysis>(Func)), LIS(LIS), + MRI(&Func.getRegInfo()), LIS(LIS), OptLevel(Func.getTarget().getOptLevel()) {} TwoAddressInstructionImpl::TwoAddressInstructionImpl(MachineFunction &Func, @@ -281,8 +275,6 @@ TwoAddressInstructionImpl::TwoAddressInstructionImpl(MachineFunction &Func, TRI(Func.getSubtarget().getRegisterInfo()), InstrItins(Func.getSubtarget().getInstrItineraryData()), MRI(&Func.getRegInfo()), OptLevel(Func.getTarget().getOptLevel()) { - auto *LVWrapper = P->getAnalysisIfAvailable<LiveVariablesWrapperPass>(); - LV = LVWrapper ? &LVWrapper->getLV() : nullptr; auto *LISWrapper = P->getAnalysisIfAvailable<LiveIntervalsWrapperPass>(); LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr; } @@ -803,7 +795,7 @@ bool TwoAddressInstructionImpl::convertInstTo3Addr( MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, Register RegA, Register RegB, unsigned &Dist) { MachineInstrSpan MIS(mi, MBB); - MachineInstr *NewMI = TII->convertToThreeAddress(*mi, LV, LIS); + MachineInstr *NewMI = TII->convertToThreeAddress(*mi, nullptr, LIS); if (!NewMI) return false; @@ -929,9 +921,9 @@ void TwoAddressInstructionImpl::processCopy(MachineInstr *MI) { bool TwoAddressInstructionImpl::rescheduleMIBelowKill( MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, Register Reg) { - // Bail immediately if we don't have LV or LIS available. We use them to find - // kills efficiently. - if (!LV && !LIS) + // Bail immediately if we don't have LIS available. We use it to find kills + // efficiently. + if (!LIS) return false; MachineInstr *MI = &*mi; @@ -940,22 +932,16 @@ bool TwoAddressInstructionImpl::rescheduleMIBelowKill( // Must be created from unfolded load. Don't waste time trying this. return false; - MachineInstr *KillMI = nullptr; - if (LIS) { - LiveInterval &LI = LIS->getInterval(Reg); - assert(LI.end() != LI.begin() && - "Reg should not have empty live interval."); + LiveInterval &LI = LIS->getInterval(Reg); + assert(LI.end() != LI.begin() && "Reg should not have empty live interval."); - SlotIndex MBBEndIdx = LIS->getMBBEndIdx(MBB).getPrevSlot(); - LiveInterval::const_iterator I = LI.find(MBBEndIdx); - if (I != LI.end() && I->start < MBBEndIdx) - return false; + SlotIndex MBBEndIdx = LIS->getMBBEndIdx(MBB).getPrevSlot(); + LiveInterval::const_iterator I = LI.find(MBBEndIdx); + if (I != LI.end() && I->start < MBBEndIdx) + return false; - --I; - KillMI = LIS->getInstructionFromIndex(I->end); - } else { - KillMI = LV->getVarInfo(Reg).findKill(MBB); - } + --I; + MachineInstr *KillMI = LIS->getInstructionFromIndex(I->end); if (!KillMI || MI == KillMI || KillMI->isCopy() || KillMI->isCopyLike()) // Don't mess with copies, they may be coalesced later. return false; @@ -1062,30 +1048,23 @@ bool TwoAddressInstructionImpl::rescheduleMIBelowKill( nmi = End; MachineBasicBlock::iterator InsertPos = KillPos; - if (LIS) { - // We have to move the copies (and any interleaved debug instructions) - // first so that the MBB is still well-formed when calling handleMove(). - for (MachineBasicBlock::iterator MBBI = AfterMI; MBBI != End;) { - auto CopyMI = MBBI++; - MBB->splice(InsertPos, MBB, CopyMI); - if (!CopyMI->isDebugOrPseudoInstr()) - LIS->handleMove(*CopyMI); - InsertPos = CopyMI; - } - End = std::next(MachineBasicBlock::iterator(MI)); + // We have to move the copies (and any interleaved debug instructions) + // first so that the MBB is still well-formed when calling handleMove(). + for (MachineBasicBlock::iterator MBBI = AfterMI; MBBI != End;) { + auto CopyMI = MBBI++; + MBB->splice(InsertPos, MBB, CopyMI); + if (!CopyMI->isDebugOrPseudoInstr()) + LIS->handleMove(*CopyMI); + InsertPos = CopyMI; } + End = std::next(MachineBasicBlock::iterator(MI)); // Copies following MI may have been moved as well. MBB->splice(InsertPos, MBB, Begin, End); DistanceMap.erase(DI); - // Update live variables - if (LIS) { - LIS->handleMove(*MI); - } else { - LV->removeVirtualRegisterKilled(Reg, *KillMI); - LV->addVirtualRegisterKilled(Reg, *MI); - } + // Update live intervals. + LIS->handleMove(*MI); LLVM_DEBUG(dbgs() << "\trescheduled below kill: " << *KillMI); return true; @@ -1117,9 +1096,9 @@ bool TwoAddressInstructionImpl::isDefTooClose(Register Reg, unsigned Dist, bool TwoAddressInstructionImpl::rescheduleKillAboveMI( MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, Register Reg) { - // Bail immediately if we don't have LV or LIS available. We use them to find - // kills efficiently. - if (!LV && !LIS) + // Bail immediately if we don't have LIS available. We use it to find kills + // efficiently. + if (!LIS) return false; MachineInstr *MI = &*mi; @@ -1128,22 +1107,16 @@ bool TwoAddressInstructionImpl::rescheduleKillAboveMI( // Must be created from unfolded load. Don't waste time trying this. return false; - MachineInstr *KillMI = nullptr; - if (LIS) { - LiveInterval &LI = LIS->getInterval(Reg); - assert(LI.end() != LI.begin() && - "Reg should not have empty live interval."); + LiveInterval &LI = LIS->getInterval(Reg); + assert(LI.end() != LI.begin() && "Reg should not have empty live interval."); - SlotIndex MBBEndIdx = LIS->getMBBEndIdx(MBB).getPrevSlot(); - LiveInterval::const_iterator I = LI.find(MBBEndIdx); - if (I != LI.end() && I->start < MBBEndIdx) - return false; + SlotIndex MBBEndIdx = LIS->getMBBEndIdx(MBB).getPrevSlot(); + LiveInterval::const_iterator I = LI.find(MBBEndIdx); + if (I != LI.end() && I->start < MBBEndIdx) + return false; - --I; - KillMI = LIS->getInstructionFromIndex(I->end); - } else { - KillMI = LV->getVarInfo(Reg).findKill(MBB); - } + --I; + MachineInstr *KillMI = LIS->getInstructionFromIndex(I->end); if (!KillMI || MI == KillMI) return false; @@ -1259,13 +1232,8 @@ bool TwoAddressInstructionImpl::rescheduleKillAboveMI( nmi = std::prev(InsertPos); // Backtrack so we process the moved instr. DistanceMap.erase(DI); - // Update live variables - if (LIS) { - LIS->handleMove(*KillMI); - } else { - LV->removeVirtualRegisterKilled(Reg, *KillMI); - LV->addVirtualRegisterKilled(Reg, *MI); - } + // Update live intervals. + LIS->handleMove(*KillMI); LLVM_DEBUG(dbgs() << "\trescheduled kill: " << *KillMI); return true; @@ -1480,36 +1448,6 @@ bool TwoAddressInstructionImpl::tryInstructionTransform( if (NewMIs[1]->getOperand(NewSrcIdx).isKill()) { // Success, or at least we made an improvement. Keep the unfolded // instructions and discard the original. - if (LV) { - for (const MachineOperand &MO : MI.operands()) { - if (MO.isReg() && MO.getReg().isVirtual()) { - if (MO.isUse()) { - if (MO.isKill()) { - if (NewMIs[0]->killsRegister(MO.getReg(), /*TRI=*/nullptr)) - LV->replaceKillInstruction(MO.getReg(), MI, *NewMIs[0]); - else { - assert(NewMIs[1]->killsRegister(MO.getReg(), - /*TRI=*/nullptr) && - "Kill missing after load unfold!"); - LV->replaceKillInstruction(MO.getReg(), MI, *NewMIs[1]); - } - } - } else if (LV->removeVirtualRegisterDead(MO.getReg(), MI)) { - if (NewMIs[1]->registerDefIsDead(MO.getReg(), - /*TRI=*/nullptr)) - LV->addVirtualRegisterDead(MO.getReg(), *NewMIs[1]); - else { - assert(NewMIs[0]->registerDefIsDead(MO.getReg(), - /*TRI=*/nullptr) && - "Dead flag missing after load unfold!"); - LV->addVirtualRegisterDead(MO.getReg(), *NewMIs[0]); - } - } - } - } - LV->addVirtualRegisterKilled(Reg, *NewMIs[1]); - } - SmallVector<Register, 4> OrigRegs; if (LIS) { for (const MachineOperand &MO : MI.operands()) { @@ -1736,14 +1674,6 @@ void TwoAddressInstructionImpl::processTiedPairs(MachineInstr *MI, } } - // Update live variables for regB. - if (RemovedKillFlag && RemainingUses.none() && LV && - LV->getVarInfo(RegB).removeKill(*MI)) { - MachineBasicBlock::iterator PrevMI = MI; - --PrevMI; - LV->addVirtualRegisterKilled(RegB, *PrevMI); - } - if (RemovedKillFlag && RemainingUses.none()) SrcRegMap[LastCopiedReg] = RegB; @@ -1816,7 +1746,7 @@ bool TwoAddressInstructionImpl::processStatepoint( // 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. + // TODO: Recompute LIS information for new range here. if (LIS) { const auto &UseLI = LIS->getInterval(RegB); const auto &DefLI = LIS->getInterval(RegA); @@ -1826,14 +1756,6 @@ bool TwoAddressInstructionImpl::processStatepoint( 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))) { @@ -1861,17 +1783,6 @@ bool TwoAddressInstructionImpl::processStatepoint( } LIS->removeInterval(RegA); } - - if (LV) { - if (MI->getOperand(SrcIdx).isKill()) - LV->removeVirtualRegisterKilled(RegB, *MI); - 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); - } } return !NeedCopy; } @@ -2103,10 +2014,6 @@ void TwoAddressInstructionImpl::eliminateRegSequence( } DefEmitted = true; - // Update LiveVariables' kill info. - if (LV && isKill && !SrcReg.isPhysical()) - LV->replaceKillInstruction(SrcReg, MI, *CopyMI); - LLVM_DEBUG(dbgs() << "Inserted: " << *CopyMI); } diff --git a/llvm/test/CodeGen/Hexagon/two-addr-tied-subregs.mir b/llvm/test/CodeGen/Hexagon/two-addr-tied-subregs.mir index d5753491dbad1..be97c5971391f 100644 --- a/llvm/test/CodeGen/Hexagon/two-addr-tied-subregs.mir +++ b/llvm/test/CodeGen/Hexagon/two-addr-tied-subregs.mir @@ -1,5 +1,5 @@ -# RUN: llc -march hexagon -run-pass livevars -run-pass twoaddressinstruction -verify-machineinstrs -o - %s | FileCheck %s -# RUN: llc -march hexagon --passes='require<live-vars>,two-address-instruction' -verify-each -o - %s | FileCheck %s +# RUN: llc -march hexagon -run-pass liveintervals -run-pass twoaddressinstruction -verify-machineinstrs -o - %s | FileCheck %s +# RUN: llc -march hexagon --passes='require<live-intervals>,two-address-instruction' -verify-each -o - %s | FileCheck %s ############################################################################### @@ -21,9 +21,9 @@ body: | # # CHECK-LABEL: name: test1 # CHECK: bb.0.entry: -# CHECK: %0:doubleregs = COPY killed $d0 -# CHECK-NEXT: %1:intregs = COPY killed %0.isub_lo -# CHECK-NEXT: %1:intregs = S2_lsr_i_r_acc %1, %1, 16 +# CHECK: %0:doubleregs = COPY $d0 +# CHECK-NEXT: %1:intregs = COPY %0.isub_lo +# CHECK-NEXT: dead %1:intregs = S2_lsr_i_r_acc %1, %1, 16 ############################################################################### @@ -50,8 +50,8 @@ body: | # # CHECK-LABEL: name: test2 # CHECK: bb.0.entry: -# CHECK: %0:doubleregs = COPY killed $d0 +# CHECK: %0:doubleregs = COPY $d0 # CHECK-NEXT: %1:intregs = COPY %0.isub_lo -# CHECK-NEXT: %1:intregs = S2_lsr_i_r_acc %1, %0.isub_hi, 16 +# CHECK-NEXT: dead %1:intregs = S2_lsr_i_r_acc %1, %0.isub_hi, 16 ############################################################################### diff --git a/llvm/test/CodeGen/SystemZ/twoaddr-kill.mir b/llvm/test/CodeGen/SystemZ/twoaddr-kill.mir index 6b6745322b0f0..4779c72c4f833 100644 --- a/llvm/test/CodeGen/SystemZ/twoaddr-kill.mir +++ b/llvm/test/CodeGen/SystemZ/twoaddr-kill.mir @@ -1,5 +1,5 @@ # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py -# RUN: llc -o - %s -verify-machineinstrs -mtriple=s390x-linux-gnu -mcpu=z196 -run-pass=livevars,twoaddressinstruction | FileCheck %s +# RUN: llc -o - %s -verify-each -mtriple=s390x-linux-gnu -mcpu=z196 --passes='require<live-intervals>,two-address-instruction' | FileCheck %s # Check that the COPY from [[COPY3]] is not killed because there is a subsequent # use of [[COPY3]] in the INLINEASM instruction. @@ -13,17 +13,17 @@ body: | ; CHECK-LABEL: name: f2 ; CHECK: liveins: $r2l ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32bit = COPY killed $r2l + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32bit = COPY $r2l ; CHECK-NEXT: [[COPY1:%[0-9]+]]:grh32bit = COPY [[COPY]] ; CHECK-NEXT: $r2l = COPY [[COPY]] - ; CHECK-NEXT: $r3l = COPY killed [[COPY]] - ; CHECK-NEXT: [[COPY2:%[0-9]+]]:grh32bit = COPY killed [[COPY1]] - ; CHECK-NEXT: INLINEASM &"stepa $1, $2, $3", attdialect, regdef:GRH32Bit, def [[COPY2]], reguse tiedto:$0, [[COPY2]](tied-def 3), reguse, killed $r2l, reguse, killed $r3l - ; CHECK-NEXT: [[COPY3:%[0-9]+]]:grh32bit = COPY killed [[COPY2]] + ; CHECK-NEXT: $r3l = COPY [[COPY]] + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:grh32bit = COPY [[COPY1]] + ; CHECK-NEXT: INLINEASM &"stepa $1, $2, $3", attdialect, regdef:GRH32Bit, def [[COPY2]], reguse tiedto:$0, [[COPY2]](tied-def 3), reguse, $r2l, reguse, killed $r3l + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:grh32bit = COPY [[COPY2]] ; CHECK-NEXT: [[COPY4:%[0-9]+]]:grh32bit = COPY [[COPY3]] ; CHECK-NEXT: INLINEASM &"stepb $1, $2", attdialect, regdef-ec:GRH32Bit, def early-clobber [[COPY4]], reguse tiedto:$0, [[COPY4]](tied-def 3), reguse:GRH32Bit, [[COPY3]] - ; CHECK-NEXT: $r2l = COPY killed [[COPY4]] - ; CHECK-NEXT: Return implicit killed $r2l + ; CHECK-NEXT: $r2l = COPY [[COPY4]] + ; CHECK-NEXT: Return implicit $r2l %0:gr32bit = COPY killed $r2l %2:grh32bit = COPY %0 $r2l = COPY %0 diff --git a/llvm/test/CodeGen/X86/statepoint-cmp-sunk-past-statepoint.ll b/llvm/test/CodeGen/X86/statepoint-cmp-sunk-past-statepoint.ll index fd134df7b580e..9badeccbb8296 100644 --- a/llvm/test/CodeGen/X86/statepoint-cmp-sunk-past-statepoint.ll +++ b/llvm/test/CodeGen/X86/statepoint-cmp-sunk-past-statepoint.ll @@ -99,9 +99,9 @@ define void @test2(ptr addrspace(1) %this, i32 %0, ptr addrspace(1) %p0, ptr add ; CHECK-NEXT: successors: %bb.6(0x04000000), %bb.1(0x7c000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY8:%[0-9]+]]:gr64 = COPY [[COPY6]] - ; CHECK-NEXT: [[COPY9:%[0-9]+]]:gr64 = COPY killed [[COPY6]] + ; CHECK-NEXT: [[COPY9:%[0-9]+]]:gr64 = COPY [[COPY6]] ; CHECK-NEXT: [[COPY9:%[0-9]+]]:gr64 = nuw ADD64ri32 [[COPY9]], 8, implicit-def dead $eflags - ; CHECK-NEXT: TEST64rr killed [[COPY4]], [[COPY4]], implicit-def $eflags + ; CHECK-NEXT: TEST64rr [[COPY4]], [[COPY4]], implicit-def $eflags ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr64 = COPY [[COPY9]] ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gr64 = COPY [[COPY8]] ; CHECK-NEXT: JCC_1 %bb.1, 5, implicit killed $eflags diff --git a/llvm/test/CodeGen/X86/statepoint-vreg-unlimited-tied-opnds.ll b/llvm/test/CodeGen/X86/statepoint-vreg-unlimited-tied-opnds.ll index 662867511e39a..c872c88cfcf0b 100644 --- a/llvm/test/CodeGen/X86/statepoint-vreg-unlimited-tied-opnds.ll +++ b/llvm/test/CodeGen/X86/statepoint-vreg-unlimited-tied-opnds.ll @@ -33,24 +33,24 @@ define i32 @test_spill( ; CHECK-VREG-NEXT: ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp ; CHECK-VREG-NEXT: [[MOV64rm11:%[0-9]+]]:gr64, [[MOV64rm10:%[0-9]+]]:gr64, [[MOV64rm9:%[0-9]+]]:gr64, [[MOV64rm8:%[0-9]+]]:gr64, [[MOV64rm7:%[0-9]+]]:gr64, [[MOV64rm6:%[0-9]+]]:gr64, [[MOV64rm5:%[0-9]+]]:gr64, [[MOV64rm4:%[0-9]+]]:gr64, [[MOV64rm3:%[0-9]+]]:gr64, [[MOV64rm2:%[0-9]+]]:gr64, [[MOV64rm1:%[0-9]+]]:gr64, [[MOV64rm:%[0-9]+]]:gr64, [[COPY:%[0-9]+]]:gr64, [[COPY1:%[0-9]+]]:gr64, [[COPY2:%[0-9]+]]:gr64, [[COPY3:%[0-9]+]]:gr64, [[COPY4:%[0-9]+]]:gr64, [[COPY5:%[0-9]+]]:gr64 = STATEPOINT 0, 0, 0, @func, 2, 0, 2, 0, 2, 0, 2, 18, [[MOV64rm11]](tied-def 0), [[MOV64rm10]](tied-def 1), [[MOV64rm9]](tied-def 2), [[MOV64rm8]](tied-def 3), [[MOV64rm7]](tied-def 4), [[MOV64rm6]](tied-def 5), [[MOV64rm5]](tied-def 6), [[MOV64rm4]](tied-def 7), [[MOV64rm3]](tied-def 8), [[MOV64rm2]](tied-def 9), [[MOV64rm1]](tied-def 10), [[MOV64rm]](tied-def 11), [[COPY]](tied-def 12), [[COPY1]](tied-def 13), [[COPY2]](tied-def 14), [[COPY3]](tied-def 15), [[COPY4]](tied-def 16), [[COPY5]](tied-def 17), 2, 0, 2, 18, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, csr_64, implicit-def $rsp, implicit-def $ssp ; CHECK-VREG-NEXT: ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp - ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm killed [[COPY5]], 1, $noreg, 4, $noreg :: (load (s32) from %ir.gep00, addrspace 1) - ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], killed [[COPY4]], 1, $noreg, 8, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep01, addrspace 1) - ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], killed [[COPY3]], 1, $noreg, 12, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep02, addrspace 1) - ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], killed [[COPY2]], 1, $noreg, 16, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep03, addrspace 1) - ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], killed [[COPY1]], 1, $noreg, 20, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep04, addrspace 1) - ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], killed [[COPY]], 1, $noreg, 24, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep05, addrspace 1) - ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], killed [[MOV64rm]], 1, $noreg, 28, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep06, addrspace 1) - ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], killed [[MOV64rm1]], 1, $noreg, 32, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep07, addrspace 1) - ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], killed [[MOV64rm2]], 1, $noreg, 36, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep08, addrspace 1) - ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], killed [[MOV64rm3]], 1, $noreg, 40, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep09, addrspace 1) - ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], killed [[MOV64rm4]], 1, $noreg, 44, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep10, addrspace 1) - ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], killed [[MOV64rm5]], 1, $noreg, 48, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep11, addrspace 1) - ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], killed [[MOV64rm6]], 1, $noreg, 52, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep12, addrspace 1) - ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], killed [[MOV64rm7]], 1, $noreg, 56, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep13, addrspace 1) - ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], killed [[MOV64rm8]], 1, $noreg, 60, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep14, addrspace 1) - ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], killed [[MOV64rm9]], 1, $noreg, 64, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep15, addrspace 1) - ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], killed [[MOV64rm10]], 1, $noreg, 68, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep16, addrspace 1) - ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], killed [[MOV64rm11]], 1, $noreg, 72, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep17, addrspace 1) + ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm [[COPY5]], 1, $noreg, 4, $noreg :: (load (s32) from %ir.gep00, addrspace 1) + ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], [[COPY4]], 1, $noreg, 8, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep01, addrspace 1) + ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], [[COPY3]], 1, $noreg, 12, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep02, addrspace 1) + ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], [[COPY2]], 1, $noreg, 16, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep03, addrspace 1) + ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], [[COPY1]], 1, $noreg, 20, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep04, addrspace 1) + ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], [[COPY]], 1, $noreg, 24, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep05, addrspace 1) + ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], [[MOV64rm]], 1, $noreg, 28, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep06, addrspace 1) + ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], [[MOV64rm1]], 1, $noreg, 32, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep07, addrspace 1) + ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], [[MOV64rm2]], 1, $noreg, 36, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep08, addrspace 1) + ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], [[MOV64rm3]], 1, $noreg, 40, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep09, addrspace 1) + ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], [[MOV64rm4]], 1, $noreg, 44, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep10, addrspace 1) + ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], [[MOV64rm5]], 1, $noreg, 48, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep11, addrspace 1) + ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], [[MOV64rm6]], 1, $noreg, 52, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep12, addrspace 1) + ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], [[MOV64rm7]], 1, $noreg, 56, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep13, addrspace 1) + ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], [[MOV64rm8]], 1, $noreg, 60, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep14, addrspace 1) + ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], [[MOV64rm9]], 1, $noreg, 64, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep15, addrspace 1) + ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], [[MOV64rm10]], 1, $noreg, 68, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep16, addrspace 1) + ; CHECK-VREG-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = ADD32rm [[MOV32rm]], [[MOV64rm11]], 1, $noreg, 72, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.gep17, addrspace 1) ; CHECK-VREG-NEXT: $eax = COPY [[MOV32rm]] ; CHECK-VREG-NEXT: RET 0, killed $eax ; diff --git a/llvm/test/CodeGen/X86/two-address-subreg-to-reg-kill.mir b/llvm/test/CodeGen/X86/two-address-subreg-to-reg-kill.mir index dbbcff0498ded..392254449c70d 100644 --- a/llvm/test/CodeGen/X86/two-address-subreg-to-reg-kill.mir +++ b/llvm/test/CodeGen/X86/two-address-subreg-to-reg-kill.mir @@ -1,7 +1,7 @@ # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6 -# RUN: llc -mtriple=x86_64-unknown-linux-gnu --run-pass=livevars,twoaddressinstruction %s -o - | FileCheck %s +# RUN: llc -mtriple=x86_64-unknown-linux-gnu --passes='require<live-intervals>,two-address-instruction' %s -o - | FileCheck %s -# Positive case: IMUL32rm with %1 as a tied source should be hoisted +# Positive case: IMUL32rm with %1 as a tied source should be hoisted # before the pass, subreg_to_reg kills a 32-bit vreg (%1) and writes to # physical $eax, which allows IMUL32rm can use %eax. --- @@ -19,9 +19,14 @@ body: | liveins: $rdi, $esi ; CHECK-LABEL: name: subreg_to_reg_kill_hoist - ; CHECK: [[COPY1:%[0-9]+]]:gr32 = COPY killed $esi + ; CHECK: liveins: $rdi, $esi + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $esi ; CHECK-NEXT: dead $rax = SUBREG_TO_REG [[COPY1]], %subreg.sub_32bit - ; CHECK: IMUL32rm + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY [[COPY1]] + ; CHECK-NEXT: dead [[COPY2:%[0-9]+]]:gr32 = IMUL32rm [[COPY2]], [[COPY]], 1, $noreg, 4, $noreg, implicit-def dead $eflags :: (load (s32) from `ptr undef`) + ; CHECK-NEXT: RET 0 %0:gr64 = COPY killed $rdi %1:gr32 = COPY killed $esi dead %2:gr32 = IMUL32rm %1, %0, 1, $noreg, 4, $noreg, implicit-def dead $eflags :: (load (s32) from `ptr undef`, align 4) @@ -45,10 +50,6 @@ body: | bb.0: liveins: $rdi, $esi - ; CHECK-LABEL: name: subreg_to_reg_virtual_dst_no_hoist - ; CHECK: MOV32rm - ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY - ; CHECK-NEXT: dead [[COPY2]]:gr32 = IMUL32rr [[COPY2]], %1, implicit-def dead $eflags %0:gr64 = COPY killed $rdi %1:gr32 = COPY killed $esi dead %2:gr32 = IMUL32rm %1, %0, 1, $noreg, 4, $noreg, implicit-def dead $eflags :: (load (s32) from `ptr undef`, align 4) @@ -70,10 +71,6 @@ body: | bb.0: liveins: $rdi, $esi - ; CHECK-LABEL: name: copy_kill_hoist - ; CHECK: [[COPY1:%[0-9]+]]:gr32 = COPY killed $esi - ; CHECK-NEXT: dead $eax = COPY [[COPY1]] - ; CHECK: IMUL32rm %0:gr64 = COPY killed $rdi %1:gr32 = COPY killed $esi dead %2:gr32 = IMUL32rm %1, %0, 1, $noreg, 4, $noreg, implicit-def dead $eflags :: (load (s32) from `ptr undef`, align 4) @@ -96,10 +93,6 @@ body: | bb.0: liveins: $rdi, $esi - ; CHECK-LABEL: name: copy_virtual_dst_no_hoist - ; CHECK: MOV32rm - ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY - ; CHECK-NEXT: dead [[COPY2]]:gr32 = IMUL32rr [[COPY2]], %1, implicit-def dead $eflags %0:gr64 = COPY killed $rdi %1:gr32 = COPY killed $esi dead %2:gr32 = IMUL32rm %1, %0, 1, $noreg, 4, $noreg, implicit-def dead $eflags :: (load (s32) from `ptr undef`, align 4) diff --git a/llvm/test/CodeGen/X86/twoaddr-dbg-value.mir b/llvm/test/CodeGen/X86/twoaddr-dbg-value.mir index d931ed04e53a5..7af76aa73ab7d 100644 --- a/llvm/test/CodeGen/X86/twoaddr-dbg-value.mir +++ b/llvm/test/CodeGen/X86/twoaddr-dbg-value.mir @@ -1,4 +1,4 @@ -# RUN: llc -run-pass=livevars,twoaddressinstruction -mtriple=x86_64-- -o - %s | FileCheck %s +# RUN: llc --passes='require<live-intervals>,two-address-instruction' -mtriple=x86_64-- -o - %s | FileCheck %s --- name: foo tracksRegLiveness: true @@ -21,7 +21,7 @@ body: | # TwoAddressInstructionPass::rescheduleMIBelowKill optimization # CHECK: PUSH32r %1, implicit-def $esp, implicit $esp -# CHECK-NEXT: %2:gr32 = COPY killed %1 +# CHECK-NEXT: %2:gr32 = COPY %1 # CHECK-NEXT: %2:gr32 = XOR32ri %2, 1, implicit-def dead $eflags +# CHECK-NEXT: %3:gr32 = COPY %2 # CHECK-NEXT: DBG_VALUE %2 -# CHECK-NEXT: %3:gr32 = COPY killed %2 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
