[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