[llvm] [polly] [SCEV] Introduce SDiv expressions (PR #216862)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 19 20:48:54 PDT 2026
================
@@ -3499,36 +3514,56 @@ const SCEV *ScalarEvolution::getURemExpr(SCEVUse LHS, SCEVUse RHS) {
/// Get a canonical unsigned division expression, or something simpler if
/// possible.
-const SCEV *ScalarEvolution::getUDivExpr(SCEVUse LHS, SCEVUse RHS) {
+const SCEV *ScalarEvolution::getDivExpr(bool IsSigned, SCEVUse LHS,
+ SCEVUse RHS) {
assert(!LHS->getType()->isPointerTy() &&
- "SCEVUDivExpr operand can't be pointer!");
+ "SCEVDivExpr operand can't be pointer!");
assert(LHS->getType() == RHS->getType() &&
- "SCEVUDivExpr operand types don't match!");
+ "SCEVDivExpr operand types don't match!");
- if (SCEV *S =
- findExistingSCEVInCache(scUDivExpr, ArrayRef<SCEVUse>({LHS, RHS})))
+ if (SCEV *S = findExistingSCEVInCache(IsSigned ? scSDivExpr : scUDivExpr,
+ ArrayRef<SCEVUse>({LHS, RHS})))
return S;
- // 0 udiv Y == 0
+ auto AnyExtend = [&](const SCEV *S, Type *Ty) {
+ return IsSigned ? getSignExtendExpr(S, Ty) : getZeroExtendExpr(S, Ty);
+ };
+
+ if (IsSigned && isKnownNonNegative(LHS) && isKnownNonNegative(RHS))
+ return getDivExpr(false, LHS, RHS);
+
+ // 0/y --> 0
if (match(LHS, m_scev_Zero()))
return LHS;
if (const SCEVConstant *RHSC = dyn_cast<SCEVConstant>(RHS)) {
if (RHSC->getValue()->isOne())
- return LHS; // X udiv 1 --> x
- // If the denominator is zero, the result of the udiv is undefined. Don't
- // try to analyze it, because the resolution chosen here may differ from
- // the resolution chosen in other parts of the compiler.
- if (!RHSC->getValue()->isZero()) {
+ return LHS; // x/1 --> x
+ // If the denominator is zero, the result of the both udiv and sdiv are
+ // undefined. Similarly if the denominator of is -1, and the numerator is
+ // INT_MIN, sdiv is undefined. Don't try to analyze it, because the
+ // resolution chosen here may differ from the resolution chosen in other
+ // parts of the compiler.
+ Type *Ty = LHS->getType();
+ unsigned BW = Ty->getIntegerBitWidth();
+ bool DivIsUndefined = RHSC->getValue()->isZero();
+ bool SDivIsUndefined =
+ RHSC->getValue()->isAllOnesValue() &&
+ getSignedRangeMin(LHS) == APInt::getSignedMinValue(BW);
+ if (!DivIsUndefined && (!IsSigned || !SDivIsUndefined)) {
+ if (IsSigned && RHSC->getValue()->isAllOnesValue())
+ return getNegativeSCEV(LHS); // x/-1 --> -x
+
// 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 LZ = IsSigned ? RHSC->getAPInt().countl_one()
----------------
artagnon wrote:
The code should be gone now.
https://github.com/llvm/llvm-project/pull/216862
More information about the llvm-commits
mailing list