[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