[llvm] [InstCombine] Introduce `foldICmpBinOpWithConstantViaTruthTable` folding (PR #139109)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Sat May 10 23:57:15 PDT 2025


================
@@ -3110,6 +3086,45 @@ static Value *createLogicFromTable(const std::bitset<4> &Table, Value *Op0,
   return nullptr;
 }
 
+Instruction *InstCombinerImpl::foldICmpBinOpWithConstantViaTruthTable(
+    ICmpInst &Cmp, BinaryOperator *BO, const APInt &C) {
+  Value *A, *B;
+  Constant *C1, *C2, *C3, *C4;
+  if (match(BO->getOperand(0),
+            m_Select(m_Value(A), m_Constant(C1), m_Constant(C2))) &&
+      match(BO->getOperand(1),
+            m_Select(m_Value(B), m_Constant(C3), m_Constant(C4)))) {
+    std::bitset<4> Table;
+    auto ComputeTable = [&](bool First, bool Second) -> std::optional<bool> {
+      Constant *L = First ? C1 : C2;
+      Constant *R = Second ? C3 : C4;
+      if (auto *Res = ConstantFoldBinaryOpOperands(BO->getOpcode(), L, R, DL)) {
+        auto *Val = Res->getType()->isVectorTy() ? Res->getSplatValue() : Res;
+        if (auto *CI = dyn_cast_or_null<ConstantInt>(Val))
+          return ICmpInst::compare(CI->getValue(), C, Cmp.getPredicate());
+      }
+      return std::nullopt;
+    };
+
+    for (unsigned I = 0; I < 4; ++I) {
+      bool First = (I >> 1) & 1;
+      bool Second = I & 1;
+      if (auto Res = ComputeTable(First, Second))
+        Table[I] = *Res;
+      else
+        return nullptr;
+    }
+
+    // Synthesize optimal logic.
+    if (auto *Cond =
+            createLogicFromTable(Table, A, B, Builder, BO->hasOneUse());
+        Cond && Cmp.getType() == Cond->getType())
----------------
dtcxzyw wrote:

If `Cmp.getType() != Cond->getType()`, the newly created instruction will not be used. It is the root cause of https://github.com/llvm/llvm-project/pull/139109/files#r2083295338.



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


More information about the llvm-commits mailing list