[llvm] [InstCombine] optimize unnecessary sext instruction with add + cmp (PR #152291)

Gaurav Dhingra via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 14 07:40:19 PDT 2025


================
@@ -6381,6 +6381,82 @@ Instruction *InstCombinerImpl::foldICmpWithZextOrSext(ICmpInst &ICmp) {
   return new ICmpInst(CmpInst::ICMP_SLT, X, Constant::getNullValue(SrcTy));
 }
 
+Instruction *InstCombinerImpl::foldICmpWithSextAndAdd(ICmpInst &ICmp) {
+  Value *X;
+  Value *Y, *Z;
+  // Match the pattern: icmp ult (add (sext X), Y), Z
+  // where X is a value, Y and Z are integer constants
+  // icmp ult (add(sext(X), Y)), Z  -> icmp ult (add(X, Y)), Z
+  if (match(&ICmp, m_SpecificICmp(CmpInst::ICMP_ULT,
+                                  m_Add(m_SExt(m_Value(X)), m_Value(Y)),
+                                  m_Value(Z)))) {
+    Type *XType = X->getType();
+    if (!XType->isIntegerTy())
+      return nullptr;
+
+    unsigned XBitWidth = XType->getIntegerBitWidth();
+    auto ExtractValue = [&](Value *V, Type *TargetType,
+                            int64_t &OutValue) -> Value * {
+      if (auto *C = dyn_cast<ConstantInt>(V)) {
+        OutValue = C->getSExtValue();
+        return ConstantInt::get(TargetType, OutValue);
+      }
+      if (match(V, m_SExt(m_Value()))) {
+        Value *Src = cast<SExtInst>(V)->getOperand(0);
+        if (Src->getType() == TargetType)
+          return Src;
+      }
+      return nullptr;
+    };
+
+    int64_t YValue, ZValue;
+    Value *NewY = ExtractValue(Y, XType, YValue);
+    Value *NewZ = ExtractValue(Z, XType, ZValue);
+    if (!NewY || !NewZ)
+      return nullptr;
+
+    bool AreYZVariables =
+        match(Y, m_SExt(m_Value())) && match(Z, m_SExt(m_Value()));
+    if (AreYZVariables) {
+      bool FoundCondition = false;
+      BasicBlock *BB = ICmp.getParent();
+      for (Instruction &I : *BB) {
+        if (auto *Assume = dyn_cast<IntrinsicInst>(&I)) {
+          if (Assume->getIntrinsicID() == Intrinsic::assume) {
+            Value *Cond = Assume->getOperand(0);
+            ConstantInt *C;
+            APInt MaxValue(Z->getType()->getIntegerBitWidth(), 1);
+            MaxValue <<= (XBitWidth - 1);
+            APInt Limit = MaxValue;
+            Limit += 1;
+            if (match(Cond, m_SpecificICmp(
+                                CmpInst::ICMP_ULT,
+                                m_Sub(m_SExt(m_Value(Y)), m_SExt(m_Value(Z))),
+                                m_ConstantInt(C))) &&
+                C->getValue().ule(Limit)) {
+              FoundCondition = true;
+              if (Assume->use_empty()) {
+                eraseInstFromFunction(*Assume);
+              }
+              break;
+            }
+          }
+        }
+      }
+      if (!FoundCondition)
+        return nullptr;
+    } else {
+      auto MaxValue = (1LL << (XBitWidth - 1));
+      if (YValue - ZValue > MaxValue || YValue - ZValue < -MaxValue)
----------------
gxyd wrote:

I should avoid using `int64_t` here as well and instead use `APInt` (should the bitwidth be `Z->getType()->getIntegerBitWidth()` or should it be `XBitWidth`?

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


More information about the llvm-commits mailing list