[llvm] [InstCombine] Fold sext of an nsw binop on trunc nsw into a wide nsw … (PR #228530)

Alexey Bataev via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 2 13:00:55 PDT 2026


================
@@ -1922,6 +1922,52 @@ bool TypeEvaluationHelper::canEvaluateSExtdPred(Value *V, Type *Ty) {
   return false;
 }
 
+/// Fold
+///   sext (binop nsw (trunc nsw X to iN), C) to iM
+/// to
+///   binop nsw X, sext(C)
+/// when X already has type iM. trunc nsw means X fits in iN, and nsw on the
+/// narrow binop means the result also fits in iN, so the sign-extended value
+/// is that same operation on X and the sign-extended other operand. The wide
+/// binop is nsw because its result fits in iN.
+///
+/// EvaluateInDifferentType rebuilds the binop without overflow flags. The
+/// sign-bit check then fails and visitSExt emits a shl/ashr pair, which SCEV
+/// cannot treat as a non-wrapping recurrence.
+static Instruction *foldSExtOfNSWBinOpOfTrunc(SExtInst &Sext,
+                                              const DataLayout &DL) {
+  auto *BinOp = dyn_cast<OverflowingBinaryOperator>(Sext.getOperand(0));
+  if (!BinOp || !BinOp->hasNoSignedWrap())
+    return nullptr;
+
+  auto Opc = static_cast<Instruction::BinaryOps>(BinOp->getOpcode());
+  if (Opc != Instruction::Add && Opc != Instruction::Sub &&
+      Opc != Instruction::Mul)
+    return nullptr;
+
+  Type *DestTy = Sext.getType();
+  bool SawNSWTrunc = false;
+  auto widenOperand = [&](Value *V) -> Value * {
+    Value *X;
+    if (match(V, m_NSWTrunc(m_Value(X))) && X->getType() == DestTy) {
+      SawNSWTrunc = true;
+      return X;
+    }
+    if (auto *C = dyn_cast<Constant>(V))
+      return ConstantFoldIntegerCast(C, DestTy, /*IsSigned=*/true, DL);
+    return nullptr;
+  };
+
+  Value *LHS = widenOperand(BinOp->getOperand(0));
+  Value *RHS = widenOperand(BinOp->getOperand(1));
+  if (!LHS || !RHS || !SawNSWTrunc)
----------------
alexey-bataev wrote:

```suggestion
  if (!LHS || !RHS)
```

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


More information about the llvm-commits mailing list