[llvm] fdb1623 - [AMDGPU] Teach SILateBranchLowering pass to preserve MachineLoopInfo (#178276)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 29 08:53:05 PST 2026
Author: Dark Steve
Date: 2026-01-29T22:23:00+05:30
New Revision: fdb16234505805a028f04397bca18b1bee4a6ab0
URL: https://github.com/llvm/llvm-project/commit/fdb16234505805a028f04397bca18b1bee4a6ab0
DIFF: https://github.com/llvm/llvm-project/commit/fdb16234505805a028f04397bca18b1bee4a6ab0.diff
LOG: [AMDGPU] Teach SILateBranchLowering pass to preserve MachineLoopInfo (#178276)
When splitting blocks inside loops due to SI_EARLY_TERMINATE_SCC0
handling, add the split block to the loop to keep MachineLoopInfo valid.
Added:
llvm/test/CodeGen/AMDGPU/si-late-branch-lowering-preserve-loop-info.mir
Modified:
llvm/lib/Target/AMDGPU/SILateBranchLowering.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/AMDGPU/SILateBranchLowering.cpp b/llvm/lib/Target/AMDGPU/SILateBranchLowering.cpp
index d6f175e67ea40..83cf457dfac13 100644
--- a/llvm/lib/Target/AMDGPU/SILateBranchLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SILateBranchLowering.cpp
@@ -17,6 +17,7 @@
#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
#include "SIMachineFunctionInfo.h"
#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachinePassManager.h"
#include "llvm/InitializePasses.h"
@@ -32,6 +33,7 @@ class SILateBranchLowering {
const SIInstrInfo *TII;
const SIRegisterInfo *TRI;
MachineDominatorTree *MDT;
+ MachineLoopInfo *MLI;
const AMDGPU::LaneMaskConstants &LMC;
void expandChainCall(MachineInstr &MI, const GCNSubtarget &ST,
@@ -39,9 +41,10 @@ class SILateBranchLowering {
void earlyTerm(MachineInstr &MI, MachineBasicBlock *EarlyExitBlock);
public:
- SILateBranchLowering(const GCNSubtarget &ST, MachineDominatorTree *MDT)
+ SILateBranchLowering(const GCNSubtarget &ST, MachineDominatorTree *MDT,
+ MachineLoopInfo *MLI)
: ST(ST), TII(ST.getInstrInfo()), TRI(&TII->getRegisterInfo()), MDT(MDT),
- LMC(AMDGPU::LaneMaskConstants::get(ST)) {}
+ MLI(MLI), LMC(AMDGPU::LaneMaskConstants::get(ST)) {}
bool run(MachineFunction &MF);
};
@@ -54,7 +57,9 @@ class SILateBranchLoweringLegacy : public MachineFunctionPass {
bool runOnMachineFunction(MachineFunction &MF) override {
const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
auto *MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
- return SILateBranchLowering(ST, MDT).run(MF);
+ auto *MLIWP = getAnalysisIfAvailable<MachineLoopInfoWrapperPass>();
+ MachineLoopInfo *MLI = MLIWP ? &MLIWP->getLI() : nullptr;
+ return SILateBranchLowering(ST, MDT, MLI).run(MF);
}
StringRef getPassName() const override {
@@ -64,6 +69,7 @@ class SILateBranchLoweringLegacy : public MachineFunctionPass {
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<MachineDominatorTreeWrapperPass>();
AU.addPreserved<MachineDominatorTreeWrapperPass>();
+ AU.addPreserved<MachineLoopInfoWrapperPass>();
MachineFunctionPass::getAnalysisUsage(AU);
}
};
@@ -117,7 +123,7 @@ static void generateEndPgm(MachineBasicBlock &MBB,
}
static void splitBlock(MachineBasicBlock &MBB, MachineInstr &MI,
- MachineDominatorTree *MDT) {
+ MachineDominatorTree *MDT, MachineLoopInfo *MLI) {
MachineBasicBlock *SplitBB = MBB.splitAt(MI, /*UpdateLiveIns*/ true);
// Update dominator tree
@@ -129,6 +135,12 @@ static void splitBlock(MachineBasicBlock &MBB, MachineInstr &MI,
}
DTUpdates.push_back({DomTreeT::Insert, &MBB, SplitBB});
MDT->applyUpdates(DTUpdates);
+
+ // Update loop info if available
+ if (MLI) {
+ if (MachineLoop *Loop = MLI->getLoopFor(&MBB))
+ Loop->addBasicBlockToLoop(SplitBB, *MLI);
+ }
}
static void copyOpWithoutRegFlags(MachineInstrBuilder &MIB,
@@ -199,7 +211,7 @@ void SILateBranchLowering::earlyTerm(MachineInstr &MI,
auto Next = std::next(MI.getIterator());
if (Next != MBB.end() && !Next->isTerminator())
- splitBlock(MBB, *BranchMI, MDT);
+ splitBlock(MBB, *BranchMI, MDT, MLI);
MBB.addSuccessor(EarlyExitBlock);
MDT->insertEdge(&MBB, EarlyExitBlock);
@@ -210,11 +222,14 @@ llvm::SILateBranchLoweringPass::run(MachineFunction &MF,
MachineFunctionAnalysisManager &MFAM) {
const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
auto *MDT = &MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
- if (!SILateBranchLowering(ST, MDT).run(MF))
+ auto *MLI = MFAM.getCachedResult<MachineLoopAnalysis>(MF);
+ if (!SILateBranchLowering(ST, MDT, MLI).run(MF))
return PreservedAnalyses::all();
- return getMachineFunctionPassPreservedAnalyses()
- .preserve<MachineDominatorTreeAnalysis>();
+ auto PA = getMachineFunctionPassPreservedAnalyses();
+ PA.preserve<MachineDominatorTreeAnalysis>();
+ PA.preserve<MachineLoopAnalysis>();
+ return PA;
}
bool SILateBranchLowering::run(MachineFunction &MF) {
diff --git a/llvm/test/CodeGen/AMDGPU/si-late-branch-lowering-preserve-loop-info.mir b/llvm/test/CodeGen/AMDGPU/si-late-branch-lowering-preserve-loop-info.mir
new file mode 100644
index 0000000000000..b5c9319f809c0
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/si-late-branch-lowering-preserve-loop-info.mir
@@ -0,0 +1,36 @@
+# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -passes="require<machine-loops>,si-late-branch-lowering,print<machine-loops>" -debug-pass-manager -filetype=null %s 2>&1 | FileCheck %s
+
+# Test that MachineLoopInfo is preserved when splitting a block inside a loop
+# due to early termination handling.
+
+# CHECK: Running analysis: MachineLoopAnalysis on early_term_in_loop
+# CHECK-NEXT: Running analysis: MachineDominatorTreeAnalysis on early_term_in_loop
+# CHECK-NEXT: Running pass: SILateBranchLoweringPass on early_term_in_loop
+# CHECK-NEXT: Running pass: MachineLoopPrinterPass on early_term_in_loop
+# CHECK-NEXT: Machine loop info for machine function 'early_term_in_loop':
+# CHECK-NOT: Running analysis: MachineLoopAnalysis on early_term_in_loop
+# CHECK-NEXT: Loop at depth 1 containing: %bb.1<header><exiting>,%bb.4<latch><exiting>
+
+---
+name: early_term_in_loop
+tracksRegLiveness: true
+body: |
+ bb.0:
+ successors: %bb.1
+ $vgpr0 = V_MOV_B32_e32 0, implicit $exec
+
+ ; Loop header contains SI_EARLY_TERMINATE_SCC0 followed by more instructions.
+ ; This triggers block splitting. Both bb.1 and bb.4 must remain in the loop.
+ bb.1:
+ liveins: $vgpr0
+ successors: %bb.1, %bb.2
+ S_CMP_LG_U32 0, 1, implicit-def $scc
+ SI_EARLY_TERMINATE_SCC0 implicit $scc, implicit $exec
+ $vgpr1 = V_MOV_B32_e32 1, implicit $exec
+ S_CBRANCH_SCC1 %bb.1, implicit $scc
+
+ bb.2:
+ liveins: $vgpr0, $vgpr1
+ EXP_DONE 0, $vgpr0, $vgpr0, $vgpr0, $vgpr0, -1, -1, 15, implicit $exec
+ S_ENDPGM 0
+...
More information about the llvm-commits
mailing list