[llvm] [AMDGPU] Fold away S_AND of a lane mask with EXEC (PR #227729)
Lukas Sommer via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 1 05:41:59 PDT 2026
================
@@ -1947,6 +1949,58 @@ bool SIFoldOperandsImpl::tryFoldRedundantAND(MachineInstr &ChildMI) const {
return true;
}
+/// Remove S_AND of a lane mask with EXEC, when the lane mask is already known
+/// to have 0 in the bits of all inactive lanes.
+///
+/// Instruction selection inserts these unconditionally because it has not
+/// analysed what produced the lane mask.
+bool SIFoldOperandsImpl::tryFoldAndExec(MachineInstr &MI) const {
+ const AMDGPU::LaneMaskConstants &LMC = AMDGPU::LaneMaskConstants::get(*ST);
+ if (MI.getOpcode() != LMC.AndOpc)
+ return false;
+
+ // The AND is going to be removed, so nothing may use the SCC it defines.
+ if (!MI.allImplicitDefsAreDead())
+ return false;
+
+ // Find the EXEC operand, and the lane mask it is being ANDed with.
+ unsigned ExecIdx = 0;
+ for (unsigned I : {1u, 2u}) {
+ const MachineOperand &MO = MI.getOperand(I);
+ if (MO.isReg() && MO.getReg() == LMC.ExecReg)
+ ExecIdx = I;
+ }
+ if (!ExecIdx)
+ return false;
+ MachineOperand &Src = MI.getOperand(3 - ExecIdx);
+ if (!Src.isReg() || !Src.getReg().isVirtual() || Src.getSubReg())
+ return false;
+
+ Register SrcReg = Src.getReg();
+ if (!TII->isMaskedByExec(SrcReg, MI, *MRI))
----------------
sommerlukas wrote:
What would happen if `EXEC` was modified between the definition of `SrcReg` and `MI`?
Something like:
```
%0:sreg_64_xexec = V_CMP_LT_I32_e64 $vgpr0, $vgpr1, implicit $exec
$exec = S_AND_B64 $exec, $sgpr0_sgpr1, implicit-def dead $scc
%1:sreg_64_xexec = S_AND_B64 $exec, %0, implicit-def dead $scc
$vcc = COPY %1
```
`isMaskedByExec` only seems to check for definition and use to be in the same block.
https://github.com/llvm/llvm-project/pull/227729
More information about the llvm-commits
mailing list