[llvm] [InstCombine] fold icmp of select with constants and invertible op (PR #147182)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 6 07:03:44 PDT 2025


================
@@ -4391,6 +4483,24 @@ Instruction *InstCombinerImpl::foldSelectICmp(CmpPredicate Pred, SelectInst *SI,
     return SelectInst::Create(SI->getOperand(0), Op1, Op2);
   }
 
+  // fold select with constants and invertible op
+  Value *Cond;
+  const APInt *C1, *C2;
+  auto *RHSOp = dyn_cast<Operator>(RHS);
+  if (RHSOp &&
+      match(SI, m_OneUse(m_Select(m_Value(Cond), m_APInt(C1), m_APInt(C2))))) {
+    if (auto Values0 = getInvertibleOperandsWithPredicte(RHSOp, *C1, Pred)) {
+      if (auto Values1 = getInvertibleOperandsWithPredicte(RHSOp, *C2, Pred)) {
+        assert(Values0->first == Values1->first &&
+               "Invertible Operand0 mismatch");
+        auto *NewSI = Builder.CreateSelect(Cond, Values0->second,
+                                           Values1->second, SI->getName());
+        return ICmpInst::Create(Instruction::ICmp, I.getPredicate(), NewSI,
----------------
dtcxzyw wrote:

```suggestion
        return ICmpInst::Create(Instruction::ICmp, Pred, NewSI,
```
Miscompilation reproducer: https://alive2.llvm.org/ce/z/RBpncq
```
define i1 @src(i8 %a, i1 %cond) {
  %a_shl1 = lshr exact i8 %a, 1
  %sel = select i1 %cond, i8 12, i8 4
  %cmp = icmp uge i8 %a_shl1, %sel
  ret i1 %cmp
}

define i1 @tgt(i8 %a, i1 %cond) {
  %sel1 = select i1 %cond, i8 24, i8 8
  %cmp = icmp uge i8 %sel1, %a
  ret i1 %cmp
}
```

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


More information about the llvm-commits mailing list