[llvm] [AMDGPU] Fix SIFoldOperands miscompiling values that leave a divergent loop (PR #203256)
Sameer Sahasrabuddhe via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 11 22:07:25 PDT 2026
================
@@ -970,6 +982,22 @@ bool SIFoldOperandsImpl::isUseSafeToFold(const MachineInstr &MI,
return !TII->isSDWA(MI);
}
+// An SGPR->VGPR copy inside a divergent loop latches each lane value as it
+// exits. Folding its scalar source into a use after the loop would make every
+// lane read the same reconverged value, so do not fold across the loop exit.
+bool SIFoldOperandsImpl::isRegFoldSafeAcrossLoopExit(
+ const FoldableDef &OpToFold, const MachineInstr &UseMI) const {
+ if (!OpToFold.isReg())
+ return true;
+ const MachineInstr *DefMI = OpToFold.DefMI;
+ if (!DefMI || !DefMI->isCopy() ||
+ TRI->isSGPRReg(*MRI, DefMI->getOperand(0).getReg()) ||
+ !TRI->isSGPRReg(*MRI, OpToFold.getReg()))
+ return true;
+ const MachineLoop *DefLoop = MLI->getLoopFor(DefMI->getParent());
+ return !DefLoop || DefLoop->contains(UseMI.getParent());
----------------
ssahasra wrote:
This feels like the code is merely asking if the value is "divergent at use", which is a sign of temporal divergence as @jayfoad pointed out. This is something that UniformityAnalysis reports. It would be nice if we could just use UA here, but the analysis itself is expensive. So if we do want to just locally check the loop like this, it will be good to rename the function as `isTemporallyDivergent()`. That will make this change mostly self-explanatory.
Attn @PankajDwivedi-25 ... another use-case for having UA readily available in the backend.
https://github.com/llvm/llvm-project/pull/203256
More information about the llvm-commits
mailing list