[llvm] [AMDGPU] Use s_cmovk_i32 instead of s_cselect_b32 when applicable (PR #135232)

Ryan Buchner via llvm-commits llvm-commits at lists.llvm.org
Thu May 1 12:05:35 PDT 2025


================
@@ -883,6 +883,50 @@ bool SIShrinkInstructions::run(MachineFunction &MF) {
         }
       }
 
+      // Try to use S_MOVK_I32
+      if (MI.getOpcode() == AMDGPU::S_CSELECT_B32) {
+        const MachineOperand *Dest = &MI.getOperand(0);
+        MachineOperand *Src0 = &MI.getOperand(1);
+        MachineOperand *Src1 = &MI.getOperand(2);
+        // Must be exactly one Immediate
+        if (!(Src0->isReg() ^ Src1->isReg()))
+          continue;
+
+        bool swapped = false;
+        // Don't actually swap the MachineOperands yet
+        // Could do it now, but don't want to since will modify generated
+        // program even in cases where we don't insert a S_CMOVK_I32
+        if (!Src0->isReg() && Src1->isReg()) {
+          swapped = true;
+          std::swap(Src0, Src1);
+        }
+
+        if (!(Src1->isImm() && isKImmOperand(*Src1)))
----------------
bababuck wrote:

> demorgan condition

Changed.

> also should work with non-register operand

A little confused by this, my understanding is that for the transformation to occur is `RD = S_CSELECT_B32 SRC0, SRC1` where `RD == SRC0` and `SRC1` is a K-Immediate. It's a little unclear to me which operand you are suggesting could be a non-register operand. If SRC0 is an immediate, then in order to use `S_CMOVK_B32` it would require a 2-instruction sequence:
```
S_MOV_B32 $sgpr0, 0x1234
S_CMOVK $sgpr0, 0x5678, implicit $scc
```
as opposed to:
```
S_CSELECT $sgpr0, 0x1234, 0x5678, implicit $scc
```


https://github.com/llvm/llvm-project/pull/135232


More information about the llvm-commits mailing list