aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorFlorian Hahn <flo@fhahn.com>2025-08-15 09:30:25 +0100
committerGitHub <noreply@github.com>2025-08-15 09:30:25 +0100
commit36be0bba2a8e45c48ae4336eff73abbcc77ee1f5 (patch)
tree1d684e7233c20140c8b340a74ddcfe2ff5841086 /llvm/lib/Analysis/ScalarEvolution.cpp
parentcfdbbb8fcc62f75dcf0b251dfab63353f3921227 (diff)
downloadllvm-36be0bba2a8e45c48ae4336eff73abbcc77ee1f5.zip
llvm-36be0bba2a8e45c48ae4336eff73abbcc77ee1f5.tar.gz
llvm-36be0bba2a8e45c48ae4336eff73abbcc77ee1f5.tar.bz2
[SCEV] Check if predicate is known false for predicated AddRecs. (#151134)
Similarly to https://github.com/llvm/llvm-project/pull/131538, we can also try and check if a predicate is known to wrap given the backedge taken count. For now, this just checks directly when we try to create predicated AddRecs. This both helps to avoid spending compile-time on optimizations where we know the predicate is false, and can also help to allow additional vectorization (e.g. by deciding to scalarize memory accesses when otherwise we would try to create a predicated AddRec with a predicate that's always false). The initial version is quite restricted, but can be extended in follow-ups to cover more cases. PR: https://github.com/llvm/llvm-project/pull/151134
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index c20b1bd..ce4d4ad 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -14952,6 +14952,29 @@ const SCEVAddRecExpr *ScalarEvolution::convertSCEVToAddRecWithPredicates(
if (!AddRec)
return nullptr;
+ // Check if any of the transformed predicates is known to be false. In that
+ // case, it doesn't make sense to convert to a predicated AddRec, as the
+ // versioned loop will never execute.
+ for (const SCEVPredicate *Pred : TransformPreds) {
+ auto *WrapPred = dyn_cast<SCEVWrapPredicate>(Pred);
+ if (!WrapPred || WrapPred->getFlags() != SCEVWrapPredicate::IncrementNSSW)
+ continue;
+
+ const SCEVAddRecExpr *AddRecToCheck = WrapPred->getExpr();
+ const SCEV *ExitCount = getBackedgeTakenCount(AddRecToCheck->getLoop());
+ if (isa<SCEVCouldNotCompute>(ExitCount))
+ continue;
+
+ const SCEV *Step = AddRecToCheck->getStepRecurrence(*this);
+ if (!Step->isOne())
+ continue;
+
+ ExitCount = getTruncateOrSignExtend(ExitCount, Step->getType());
+ const SCEV *Add = getAddExpr(AddRecToCheck->getStart(), ExitCount);
+ if (isKnownPredicate(CmpInst::ICMP_SLT, Add, AddRecToCheck->getStart()))
+ return nullptr;
+ }
+
// Since the transformation was successful, we can now transfer the SCEV
// predicates.
Preds.append(TransformPreds.begin(), TransformPreds.end());