[llvm] [AMDGPU] Remove redundant s_cmp_lg_* sX, 0 (PR #162352)

Juan Manuel Martinez CaamaƱo via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 9 00:45:54 PDT 2025


================
@@ -10608,6 +10608,63 @@ bool SIInstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
   if (SrcReg2 && !getFoldableImm(SrcReg2, *MRI, CmpValue))
     return false;
 
+  const auto optimizeCmpSelect = [&CmpInstr, SrcReg, CmpValue, MRI,
+                                  this]() -> bool {
+    if (CmpValue != 0)
+      return false;
+
+    MachineInstr *Def = MRI->getUniqueVRegDef(SrcReg);
+    if (!Def || Def->getParent() != CmpInstr.getParent())
+      return false;
+
+    bool CanOptimize = false;
+    MachineOperand *SccDef =
+        Def->findRegisterDefOperand(AMDGPU::SCC, /*TRI=*/nullptr);
+
+    // For S_OP that set SCC = DST!=0, do the transformation
+    //
+    //   s_cmp_lg_* (S_OP ...), 0 => (S_OP ...)
+    if (SccDef && Def->getOpcode() != AMDGPU::S_ADD_I32 &&
+        Def->getOpcode() != AMDGPU::S_ADD_U32 &&
+        Def->getOpcode() != AMDGPU::S_ADDC_U32 &&
+        Def->getOpcode() != AMDGPU::S_SUB_I32 &&
+        Def->getOpcode() != AMDGPU::S_SUB_U32 &&
+        Def->getOpcode() != AMDGPU::S_SUBB_U32 &&
+        Def->getOpcode() != AMDGPU::S_MIN_I32 &&
+        Def->getOpcode() != AMDGPU::S_MIN_U32 &&
+        Def->getOpcode() != AMDGPU::S_MAX_I32 &&
+        Def->getOpcode() != AMDGPU::S_MAX_U32 &&
+        Def->getOpcode() != AMDGPU::S_ADDK_I32)
+      CanOptimize = true;
+
+    // s_cmp_lg_* is redundant because the SCC input value for S_CSELECT* has
+    // the same value that will be calculated by s_cmp_lg_*
+    //
+    //   s_cmp_lg_* (S_CSELECT* (non-zero imm), 0), 0 => (S_CSELECT* (non-zero
+    //   imm), 0)
+    if ((Def->getOpcode() == AMDGPU::S_CSELECT_B32 ||
+         Def->getOpcode() == AMDGPU::S_CSELECT_B64) &&
+        Def->getOperand(1).isImm() && Def->getOperand(1).getImm() &&
+        !Def->getOperand(2).isImm() && !Def->getOperand(2).getImm())
----------------
jmmartinez wrote:

Is there a typo here ? Shouldn't this be `Def->getOperand(2).isImm() && !Def->getOperand(2).getImm()` wihtout the first `not` ?

The comment above says that the operand 2 should be an imm-zero.

Maybe it'd be clearer if we split the condition:

```cpp
if(Opcode == AMDGPU::S_CSELECT_B32 || Opcode == AMDGPU::S_CSELECT_B64) {
  //   s_cmp_lg_* (S_CSELECT* (non-zero imm), 0), 0 => (S_CSELECT* (non-zero imm), 0)
  bool Op1IsNonZeroImm = Def->getOperand(1).isImm() && Def->getOperand(1).getImm() != 0;
  bool Op2IsZeroImm = Def->getOperand(2).isImm() && Def->getOperand(2).getImm() == 0;
  if(!Op1IsNonZeroImm || !Op2IsZeroImm)
    return false;
}
```

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


More information about the llvm-commits mailing list