diff options
author | Florian Hahn <flo@fhahn.com> | 2025-08-15 09:30:25 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-08-15 09:30:25 +0100 |
commit | 36be0bba2a8e45c48ae4336eff73abbcc77ee1f5 (patch) | |
tree | 1d684e7233c20140c8b340a74ddcfe2ff5841086 /llvm/lib/Analysis/ScalarEvolution.cpp | |
parent | cfdbbb8fcc62f75dcf0b251dfab63353f3921227 (diff) | |
download | llvm-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.cpp | 23 |
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()); |