diff options
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()); |