[llvm] [InstCombine] Fold `X > C2 ? X + C1 : C2 + C1` to `max(X, C2) + C1` (PR #116888)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 22 06:37:21 PST 2024
================
@@ -1898,6 +1898,69 @@ static Instruction *foldSelectICmpEq(SelectInst &SI, ICmpInst *ICI,
return nullptr;
}
+// Turn select (Cmp X C1) (BOp X C2) C3
+// -> BOp (min/max X C1) C2
+// iff C3 == BOp C1 C2
+// This allows for better canonicalization.
+static Value *canonicalizeConstToBOp(ICmpInst *Cmp, Value *TrueVal,
+ Value *FalseVal,
+ InstCombiner::BuilderTy &Builder) {
+ BinaryOperator *BOp;
+ Constant *C1, *C2, *C3;
+ Value *X;
+ ICmpInst::Predicate Predicate;
+
+ if (!match(Cmp, m_ICmp(Predicate, m_Value(X), m_Constant(C1))))
+ return nullptr;
+
+ if (!((match(TrueVal, m_BinOp(BOp)) && match(FalseVal, m_Constant(C3))) ||
+ (match(FalseVal, m_BinOp(BOp)) && match(TrueVal, m_Constant(C3)))))
+ return nullptr;
+
+ if (!match(BOp, m_OneUse(m_c_BinOp(m_Specific(X), m_Constant(C2)))))
+ return nullptr;
+
+ // `select (Cmp X C1) (sub C2 X) (sub C1 C2)` cannot be transformed
+ // into something like `sub (select (Cmp X C1) X C1) C2`
+ if (!BOp->isCommutative() && BOp->getOperand(0) != X)
+ return nullptr;
+
+ if (!(ICmpInst::isRelational(Predicate) &&
+ C3 == ConstantFoldBinaryOpOperands(BOp->getOpcode(), C1, C2,
+ BOp->getDataLayout())))
----------------
nikic wrote:
Distribute `!` over `&&` please.
https://github.com/llvm/llvm-project/pull/116888
More information about the llvm-commits
mailing list