[llvm] [SCEV] Use 2 * BW when checking nuw of udiv-AR (NFC) (PR #219645)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 29 00:24:07 PDT 2026


https://github.com/artagnon created https://github.com/llvm/llvm-project/pull/219645

Use twice the bitwidth for the extended type when checking the AddRec in getUDiv for no-unsigned-wrap by extension: the leading-zeros analysis is unnecessary. This matches existing code that check for wrap by extension.

>From 02fe490751f0ae0e0c66a7452bd3f6ef6b575a10 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Sat, 29 Aug 2026 08:05:46 +0100
Subject: [PATCH] [SCEV] Use 2 * BW when checking nuw of udiv-AR (NFC)

Use twice the bitwidth for the extended type when checking the AddRec in
getUDiv for no-unsigned-wrap by extension: the leading-zeros analysis is
unnecessary. This matches existing code that check for wrap by
extension.
---
 llvm/lib/Analysis/ScalarEvolution.cpp | 27 ++++++++-------------------
 1 file changed, 8 insertions(+), 19 deletions(-)

diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index e81d91c03c130..c68a0f411c5ce 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -3461,26 +3461,21 @@ const SCEV *ScalarEvolution::getUDivExpr(SCEVUse LHS, SCEVUse RHS) {
       // Determine if the division can be folded into the operands of
       // its operands.
       // TODO: Generalize this to non-constants by using known-bits information.
-      Type *Ty = LHS->getType();
-      unsigned LZ = RHSC->getAPInt().countl_zero();
-      unsigned MaxShiftAmt = getTypeSizeInBits(Ty) - LZ - 1;
-      // For non-power-of-two values, effectively round the value up to the
-      // nearest power of two.
-      if (!RHSC->getAPInt().isPowerOf2())
-        ++MaxShiftAmt;
-      IntegerType *ExtTy =
-        IntegerType::get(getContext(), getTypeSizeInBits(Ty) + MaxShiftAmt);
       if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(LHS))
         if (const SCEVConstant *Step =
             dyn_cast<SCEVConstant>(AR->getStepRecurrence(*this))) {
           // {X,+,N}/C --> {X/C,+,N/C} if safe and N/C can be folded.
           const APInt &StepInt = Step->getAPInt();
           const APInt &DivInt = RHSC->getAPInt();
-          if (!StepInt.urem(DivInt) &&
+          IntegerType *ExtTy = IntegerType::get(
+              getContext(), 2 * getTypeSizeInBits(AR->getType()));
+          bool NoWrap =
+              (!StepInt.urem(DivInt) || !DivInt.urem(StepInt)) &&
               getZeroExtendExpr(AR, ExtTy) ==
-              getAddRecExpr(getZeroExtendExpr(AR->getStart(), ExtTy),
-                            getZeroExtendExpr(Step, ExtTy),
-                            AR->getLoop(), SCEV::FlagAnyWrap)) {
+                  getAddRecExpr(getZeroExtendExpr(AR->getStart(), ExtTy),
+                                getZeroExtendExpr(Step, ExtTy), AR->getLoop(),
+                                SCEV::FlagAnyWrap);
+          if (!StepInt.urem(DivInt) && NoWrap) {
             SmallVector<SCEVUse, 4> Operands;
             for (const SCEV *Op : AR->operands())
               Operands.push_back(getUDivExpr(Op, RHS));
@@ -3491,12 +3486,6 @@ const SCEV *ScalarEvolution::getUDivExpr(SCEVUse LHS, SCEVUse RHS) {
           const APInt *StartRem;
           if (!DivInt.urem(StepInt) && match(getURemExpr(AR->getStart(), Step),
                                              m_scev_APInt(StartRem))) {
-            bool NoWrap =
-                getZeroExtendExpr(AR, ExtTy) ==
-                getAddRecExpr(getZeroExtendExpr(AR->getStart(), ExtTy),
-                              getZeroExtendExpr(Step, ExtTy), AR->getLoop(),
-                              SCEV::FlagAnyWrap);
-
             // With N <= C and both N, C as powers-of-2, the transformation
             // {X,+,N}/C => {(X - X%N),+,N}/C preserves division results even
             // if wrapping occurs, as the division results remain equivalent for



More information about the llvm-commits mailing list