From aa1013740b2ce4b64d124af3da7f5bdd1919cf95 Mon Sep 17 00:00:00 2001 From: Philip Reames Date: Tue, 2 Dec 2025 13:49:37 -0800 Subject: [PATCH] [SCEV] Factor out utility for proving same sign of two SCEVs [nfc] This is a slightly different API than ConstantRange's areInsensitiveToSignednessOfICmpPredicate. The only actual difference (beyond naming) is the handling of empty ranges (i.e. unreachable code). I wanted to keep the existing SCEV behavior for the unreachable code as we should be folding that to poison, not reasoning about samesign. The new API will be reused in https://github.com/llvm/llvm-project/pull/170363. I'll rebase whichever lands second over the first to land. --- llvm/include/llvm/Analysis/ScalarEvolution.h | 3 +++ llvm/lib/Analysis/ScalarEvolution.cpp | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h index 04ea769bd06d1..6e086b55e9e99 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -1078,6 +1078,9 @@ class ScalarEvolution { isKnownMultipleOf(const SCEV *S, uint64_t M, SmallVectorImpl &Assumptions); + /// Return true if we know that S1 and S2 must have the same sign. + LLVM_ABI bool haveSameSign(const SCEV *S1, const SCEV *S2); + /// Splits SCEV expression \p S into two SCEVs. One of them is obtained from /// \p S by substitution of all AddRec sub-expression related to loop \p L /// with initial value of that SCEV. The second is obtained from \p S by diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 5f6718d6cbcd8..0ac0ca7463131 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -11115,6 +11115,11 @@ bool ScalarEvolution::isKnownMultipleOf( return true; } +bool ScalarEvolution::haveSameSign(const SCEV *S1, const SCEV *S2) { + return ((isKnownNonNegative(S1) && isKnownNonNegative(S2)) || + (isKnownNegative(S1) && isKnownNegative(S2))); +} + std::pair ScalarEvolution::SplitIntoInitAndPostInc(const Loop *L, const SCEV *S) { // Compute SCEV on entry of loop L. @@ -12034,8 +12039,7 @@ bool ScalarEvolution::isImpliedCondBalancedTypes( if (IsSignFlippedPredicate(Pred, FoundPred)) { // Unsigned comparison is the same as signed comparison when both the // operands are non-negative or negative. - if ((isKnownNonNegative(FoundLHS) && isKnownNonNegative(FoundRHS)) || - (isKnownNegative(FoundLHS) && isKnownNegative(FoundRHS))) + if (haveSameSign(FoundLHS, FoundRHS)) return isImpliedCondOperands(Pred, LHS, RHS, FoundLHS, FoundRHS, CtxI); // Create local copies that we can freely swap and canonicalize our // conditions to "le/lt".