[llvm] [InstCombine][WIP] Fold `(binop VarTwoPossibleVals, C)` to `select` (PR #101731)

via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 3 02:21:03 PDT 2024


================
@@ -4872,6 +4872,76 @@ void InstCombinerImpl::tryToSinkInstructionDbgValues(
   }
 }
 
+// Fold:
+//  (binop X, C)
+// Where X can only be one of two possible values to:
+//  (select (icmp eq X, C0), (binop C0, C), (binop C1, C))
+//
+// We don't do this for all binops, only those not handled by
+// `foldSelectICmpAnd` which does the inverse.
+Instruction *
+InstCombinerImpl::foldOpWithTwoPossibleValuesToSelect(BinaryOperator &I) {
+
+  switch (I.getOpcode()) {
+    // Handled in `foldSelectICmpAnd` where we go the other way.
+  case Instruction::Add:
+  case Instruction::Or:
+  case Instruction::Sub:
+  case Instruction::Xor:
+    return nullptr;
+  default:
+    break;
+  }
+
+  for (unsigned OpIdx = 0; OpIdx < 2; ++OpIdx) {
+    switch (I.getOpcode()) {
+    case Instruction::Shl:
+    case Instruction::AShr:
+    case Instruction::LShr:
+      if (OpIdx == 1)
+        return nullptr;
+      break;
+    default:
+      break;
+    }
+    ConstantInt *C;
+    if (!match(I.getOperand(OpIdx), m_ConstantInt(C)))
+      continue;
+
+    Value *Other = I.getOperand(1 - OpIdx);
+    KnownBits OtherKnown = computeKnownBits(Other, /*Depth=*/0, &I);
+
+    // See if the other op has only two possible values.
+    if ((OtherKnown.One | OtherKnown.Zero).popcount() !=
+        (OtherKnown.getBitWidth() - 1))
----------------
goldsteinn wrote:

What about `or X, -2`?

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


More information about the llvm-commits mailing list