[llvm] [InstCombine] Add m_NUWAdd final cases (PR #102643)

Rose Silicon via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 9 09:36:15 PDT 2024


https://github.com/RSilicon created https://github.com/llvm/llvm-project/pull/102643

None

>From 8d7f59bba91414f3eaf9484806bbc53d548c514d Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Fri, 9 Aug 2024 12:35:48 -0400
Subject: [PATCH] [InstCombine] Add m_NUWAdd final cases

---
 .../InstCombine/InstCombineSelect.cpp         | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 6bcff6f9d49efd..a5db61999d04df 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -1026,6 +1026,30 @@ static Value *canonicalizeSaturatedAdd(ICmpInst *Cmp, Value *TVal, Value *FVal,
                                          ConstantInt::get(Cmp0->getType(), *C));
   }
 
+  // Zero does not work here because X u> 0 ? -1 : X is not a saturated add.
+  if (Pred == ICmpInst::ICMP_UGT &&
+      match(FVal, m_NUWAdd(m_Specific(Cmp0), m_APIntAllowPoison(C))) &&
+      match(Cmp1, m_SpecificIntAllowPoison(-*C)) && !C->isZero()) {
+    // (X u > -C) ? -1 : (X + C) --> uadd.sat(X, C)
+    return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp0,
+                                         ConstantInt::get(Cmp0->getType(), *C));
+  }
+
+  // The constant 1 needs special handling, so it has to be exempt here. This is
+  // because -1 + 1 is 0, which means this tranformation does not hold true.
+  // Note that X u >= -1 is canonicalized as X == -1, which is handled in the
+  // special case below this transform.
+  // Zero also does not work here because X u >= 1 ? -1 : X is not a saturated
+  // add.
+  if (Pred == ICmpInst::ICMP_UGE &&
+      match(FVal, m_NUWAdd(m_Specific(Cmp0), m_APIntAllowPoison(C))) &&
+      match(Cmp1, m_SpecificIntAllowPoison(-*C + 1)) && !C->isZero() &&
+      !C->isOne()) {
+    // (X u >= -C + 1) ? -1 : (X + C) --> uadd.sat(X, C)
+    return Builder.CreateBinaryIntrinsic(Intrinsic::uadd_sat, Cmp0,
+                                         ConstantInt::get(Cmp0->getType(), *C));
+  }
+
   // Canonicalize predicate to less-than or less-or-equal-than.
   if (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_UGE) {
     std::swap(Cmp0, Cmp1);



More information about the llvm-commits mailing list