summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/lib/Analysis/ScalarEvolutionExpander.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/llvm/lib/Analysis/ScalarEvolutionExpander.cpp')
-rw-r--r--gnu/llvm/lib/Analysis/ScalarEvolutionExpander.cpp67
1 files changed, 49 insertions, 18 deletions
diff --git a/gnu/llvm/lib/Analysis/ScalarEvolutionExpander.cpp b/gnu/llvm/lib/Analysis/ScalarEvolutionExpander.cpp
index 47bdac00ae1..53ce33bacbe 100644
--- a/gnu/llvm/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/gnu/llvm/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -187,8 +187,21 @@ Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode,
// generated code.
if (isa<DbgInfoIntrinsic>(IP))
ScanLimit++;
+
+ // Conservatively, do not use any instruction which has any of wrap/exact
+ // flags installed.
+ // TODO: Instead of simply disable poison instructions we can be clever
+ // here and match SCEV to this instruction.
+ auto canGeneratePoison = [](Instruction *I) {
+ if (isa<OverflowingBinaryOperator>(I) &&
+ (I->hasNoSignedWrap() || I->hasNoUnsignedWrap()))
+ return true;
+ if (isa<PossiblyExactOperator>(I) && I->isExact())
+ return true;
+ return false;
+ };
if (IP->getOpcode() == (unsigned)Opcode && IP->getOperand(0) == LHS &&
- IP->getOperand(1) == RHS)
+ IP->getOperand(1) == RHS && !canGeneratePoison(&*IP))
return &*IP;
if (IP == BlockBegin) break;
}
@@ -878,7 +891,7 @@ bool SCEVExpander::isNormalAddRecExprPHI(PHINode *PN, Instruction *IncV,
if (IncV->mayHaveSideEffects())
return false;
- if (IncV != PN)
+ if (IncV == PN)
return true;
return isNormalAddRecExprPHI(PN, IncV, L);
@@ -1141,12 +1154,11 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
IVIncInsertLoop &&
SE.DT.properlyDominates(LatchBlock, IVIncInsertLoop->getHeader());
- for (auto &I : *L->getHeader()) {
- auto *PN = dyn_cast<PHINode>(&I);
- if (!PN || !SE.isSCEVable(PN->getType()))
+ for (PHINode &PN : L->getHeader()->phis()) {
+ if (!SE.isSCEVable(PN.getType()))
continue;
- const SCEVAddRecExpr *PhiSCEV = dyn_cast<SCEVAddRecExpr>(SE.getSCEV(PN));
+ const SCEVAddRecExpr *PhiSCEV = dyn_cast<SCEVAddRecExpr>(SE.getSCEV(&PN));
if (!PhiSCEV)
continue;
@@ -1158,16 +1170,16 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
continue;
Instruction *TempIncV =
- cast<Instruction>(PN->getIncomingValueForBlock(LatchBlock));
+ cast<Instruction>(PN.getIncomingValueForBlock(LatchBlock));
// Check whether we can reuse this PHI node.
if (LSRMode) {
- if (!isExpandedAddRecExprPHI(PN, TempIncV, L))
+ if (!isExpandedAddRecExprPHI(&PN, TempIncV, L))
continue;
if (L == IVIncInsertLoop && !hoistIVInc(TempIncV, IVIncInsertPos))
continue;
} else {
- if (!isNormalAddRecExprPHI(PN, TempIncV, L))
+ if (!isNormalAddRecExprPHI(&PN, TempIncV, L))
continue;
}
@@ -1176,7 +1188,7 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
IncV = TempIncV;
TruncTy = nullptr;
InvertStep = false;
- AddRecPhiMatch = PN;
+ AddRecPhiMatch = &PN;
break;
}
@@ -1186,7 +1198,7 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
canBeCheaplyTransformed(SE, PhiSCEV, Normalized, InvertStep)) {
// Record the phi node. But don't stop we might find an exact match
// later.
- AddRecPhiMatch = PN;
+ AddRecPhiMatch = &PN;
IncV = TempIncV;
TruncTy = SE.getEffectiveSCEVType(Normalized->getType());
}
@@ -1728,10 +1740,28 @@ Value *SCEVExpander::expand(const SCEV *S) {
InsertPt = &*L->getHeader()->getFirstInsertionPt();
}
} else {
+ // We can move insertion point only if there is no div or rem operations
+ // otherwise we are risky to move it over the check for zero denominator.
+ auto SafeToHoist = [](const SCEV *S) {
+ return !SCEVExprContains(S, [](const SCEV *S) {
+ if (const auto *D = dyn_cast<SCEVUDivExpr>(S)) {
+ if (const auto *SC = dyn_cast<SCEVConstant>(D->getRHS()))
+ // Division by non-zero constants can be hoisted.
+ return SC->getValue()->isZero();
+ // All other divisions should not be moved as they may be
+ // divisions by zero and should be kept within the
+ // conditions of the surrounding loops that guard their
+ // execution (see PR35406).
+ return true;
+ }
+ return false;
+ });
+ };
// If the SCEV is computable at this level, insert it into the header
// after the PHIs (and after any other instructions that we've inserted
// there) so that it is guaranteed to dominate any user inside the loop.
- if (L && SE.hasComputableLoopEvolution(S, L) && !PostIncLoops.count(L))
+ if (L && SE.hasComputableLoopEvolution(S, L) && !PostIncLoops.count(L) &&
+ SafeToHoist(S))
InsertPt = &*L->getHeader()->getFirstInsertionPt();
while (InsertPt->getIterator() != Builder.GetInsertPoint() &&
(isInsertedInstruction(InsertPt) ||
@@ -1828,12 +1858,8 @@ SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT,
const TargetTransformInfo *TTI) {
// Find integer phis in order of increasing width.
SmallVector<PHINode*, 8> Phis;
- for (auto &I : *L->getHeader()) {
- if (auto *PN = dyn_cast<PHINode>(&I))
- Phis.push_back(PN);
- else
- break;
- }
+ for (PHINode &PN : L->getHeader()->phis())
+ Phis.push_back(&PN);
if (TTI)
std::sort(Phis.begin(), Phis.end(), [](Value *LHS, Value *RHS) {
@@ -2293,4 +2319,9 @@ bool isSafeToExpand(const SCEV *S, ScalarEvolution &SE) {
visitAll(S, Search);
return !Search.IsUnsafe;
}
+
+bool isSafeToExpandAt(const SCEV *S, const Instruction *InsertionPoint,
+ ScalarEvolution &SE) {
+ return isSafeToExpand(S, SE) && SE.dominates(S, InsertionPoint->getParent());
+}
}