[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