[llvm-branch-commits] [llvm] CodeGen: Remove LiveVariables use from TwoAddressInstructionPass (PR #225176)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Sep 28 06:46:39 PDT 2026
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/225176
>From 31c93a202115c462e01931329f255d0523d11c41 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
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) <noreply at anthropic.com>
---
.../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
More information about the llvm-branch-commits
mailing list