[llvm] [SCEV] Factor out utility for proving same sign of two SCEVs [nfc] (PR #170376)
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 2 14:03:24 PST 2025
https://github.com/preames created https://github.com/llvm/llvm-project/pull/170376
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. I tried the other variant locally, and saw no test changes.
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.
>From aa1013740b2ce4b64d124af3da7f5bdd1919cf95 Mon Sep 17 00:00:00 2001
From: Philip Reames <preames at rivosinc.com>
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<const SCEVPredicate *> &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<const SCEV *, const SCEV *>
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".
More information about the llvm-commits
mailing list