[llvm] [InstCombine] Canonicalize signed saturated additions (PR #153053)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 14 22:49:20 PST 2025
================
@@ -1130,6 +1128,105 @@ static Value *canonicalizeSaturatedAdd(ICmpInst *Cmp, Value *TVal, Value *FVal,
return nullptr;
}
+static Value *canonicalizeSaturatedAddSigned(ICmpInst *Cmp, Value *TVal,
+ Value *FVal,
+ InstCombiner::BuilderTy &Builder) {
+ // Match saturated add with constant.
+ Value *Cmp0 = Cmp->getOperand(0);
+ Value *Cmp1 = Cmp->getOperand(1);
+ ICmpInst::Predicate Pred = Cmp->getPredicate();
+ Value *X;
+ const APInt *C;
+
+ // Canonicalize INT_MAX to true value of the select.
+ if (match(FVal, m_MaxSignedValue())) {
+ std::swap(TVal, FVal);
+ Pred = CmpInst::getInversePredicate(Pred);
+ }
+
+ if (!match(TVal, m_MaxSignedValue()))
+ return nullptr;
+
+ // sge maximum signed value is canonicalized to eq maximum signed value and
+ // requires special handling (a == INT_MAX) ? INT_MAX : a + 1 -> sadd.sat(a,
+ // 1)
+ if (Pred == ICmpInst::ICMP_EQ) {
+ if (match(FVal, m_Add(m_Specific(Cmp0), m_One())) && Cmp1 == TVal) {
+ return Builder.CreateBinaryIntrinsic(
+ Intrinsic::sadd_sat, Cmp0, ConstantInt::get(Cmp0->getType(), 1));
+ }
+ return nullptr;
+ }
+
+ // (X > Y) ? INT_MAX : (X + C) --> sadd.sat(X, C)
+ // (X >= Y) ? INT_MAX : (X + C) --> sadd.sat(X, C)
+ // where Y is INT_MAX - C or INT_MAX - C - 1, and C > 0
+ if ((Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SGE) &&
+ match(FVal, m_Add(m_Specific(Cmp0), m_APIntAllowPoison(C))) &&
+ C->isStrictlyPositive()) {
----------------
dtcxzyw wrote:
```suggestion
match(FVal, m_Add(m_Specific(Cmp0), m_StrictlyPositive(C)))) {
```
https://github.com/llvm/llvm-project/pull/153053
More information about the llvm-commits
mailing list