[llvm] [InstCombine] fold icmp of select with invertible shl (PR #147182)

via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 25 07:06:47 PDT 2025


================
@@ -5948,9 +5954,29 @@ static Instruction *foldICmpEqualityWithOffset(ICmpInst &I,
   collectOffsetOp(Op1, OffsetOps, /*AllowRecursion=*/true);
 
   auto ApplyOffsetImpl = [&](Value *V, unsigned BinOpc, Value *RHS) -> Value * {
+    switch (BinOpc) {
+    // V = shl nsw X, RHS => X = ashr V, RHS
+    case Instruction::AShr: {
+      const APInt *CV, *CRHS;
+      if (match(V, m_APInt(CV)) && match(RHS, m_APInt(CRHS)) &&
+          CV->ashr(*CRHS).shl(*CRHS) != *CV)
+        return nullptr;
+      break;
+    }
+    // V = shl nuw X, RHS => X = lshr V, RHS
+    case Instruction::LShr: {
+      const APInt *CV, *CRHS;
+      if (match(V, m_APInt(CV)) && match(RHS, m_APInt(CRHS)) &&
+          CV->lshr(*CRHS).shl(*CRHS) != *CV)
+        return nullptr;
+      break;
+    }
+    default:
+      break;
+    }
+
     Value *Simplified = simplifyBinOp(BinOpc, V, RHS, SQ);
-    // Avoid infinite loops by checking if RHS is an identity for the BinOp.
-    if (!Simplified || Simplified == V)
----------------
actinks wrote:

@dtcxzyw del `|| Simplified == V` since  `0 >> 3` simplifie to `0`
```
  %shl = shl nsw i8 %a, 3
  %sel = select i1 %cond, i8 8, i8 0
  %cmp = icmp eq i8 %shl, %sel
  ret i1 %cmp
```

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


More information about the llvm-commits mailing list