[llvm] [AMDGPU] Sink async DMA out of s_cbranch_execz then-blocks (PR #196374)
Vigneshwar Jayakumar via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 23 12:54:54 PDT 2026
================
@@ -654,6 +663,128 @@ void SILowerControlFlow::optimizeEndCf() {
}
}
+static MachineInstr *findExecRestoreAtBlockStart(MachineBasicBlock &JoinBB,
+ const SIRegisterInfo *TRI) {
+ for (MachineInstr &MI : JoinBB) {
+ if (MI.isMetaInstruction() || MI.isDebugInstr())
+ continue;
+ return MI.modifiesRegister(AMDGPU::EXEC, TRI) ? &MI : nullptr;
+ }
+ return nullptr;
+}
+
+bool SILowerControlFlow::sinkAsyncDMAOutOfExeczBlocks(MachineFunction &MF) {
+ bool Changed = false;
+
+ for (MachineBasicBlock &MBB : MF) {
+ // Header must end with an S_CBRANCH_EXECZ to JoinBB.
+ auto BrIt = llvm::find_if(MBB.terminators(), [](const MachineInstr &MI) {
+ return MI.getOpcode() == AMDGPU::S_CBRANCH_EXECZ;
+ });
+ if (BrIt == MBB.terminators().end())
+ continue;
+ MachineBasicBlock *JoinBB = BrIt->getOperand(0).getMBB();
+
+ if (MBB.succ_size() != 2)
+ continue;
+ MachineBasicBlock *S0 = *MBB.succ_begin();
+ MachineBasicBlock *S1 = *std::next(MBB.succ_begin());
+ MachineBasicBlock *ThenBB = (S0 == JoinBB) ? S1 : S0;
+ if (ThenBB == JoinBB || ThenBB->succ_size() != 1 ||
+ *ThenBB->succ_begin() != JoinBB)
+ continue;
+
+ // Sink before the EXEC restore at the top of JoinBB.
+ MachineInstr *ExecRestore = findExecRestoreAtBlockStart(*JoinBB, TRI);
+ if (!ExecRestore)
+ continue;
+
+ SmallVector<MachineInstr *, 4> ToSink;
+ bool Eligible = true;
+ for (MachineInstr &TMI : *ThenBB) {
+ if (TMI.isMetaInstruction() || TMI.isDebugInstr() || TMI.isTerminator())
+ continue;
+ if (TII->hasUnwantedEffectsWhenEXECEmpty(TMI)) {
+ Eligible = false;
+ break;
+ }
+ if (SIInstrInfo::usesASYNC_CNT(TMI)) {
+ ToSink.push_back(&TMI);
+ continue;
+ }
+ // Bail on stores that could alias the sunk DMAs.
+ if (TMI.mayStore()) {
+ Eligible = false;
+ break;
+ }
+ // Bail on non-invariant loads that could alias the sunk DMAs.
+ if (TMI.mayLoad() && !TMI.isDereferenceableInvariantLoad()) {
----------------
VigneshwarJ wrote:
when EXEC is zero, issuing the sunk DMA has no per-lane memory effect. It does not make reordering safe for waves where EXEC is nonzero.
If a non-invariant load follows an async load-to-LDS, sinking reverses their issue order. If the load may read the LDS destination written by the DMA
https://github.com/llvm/llvm-project/pull/196374
More information about the llvm-commits
mailing list