summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2015-01-22 08:29:18 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2015-01-22 08:29:18 +0000
commitd1fb13ce4c6b6563d1c725c06400e51d1d38983f (patch)
tree03c1fbf3cdfb2d375514f90c5a1f6b22df936eea /llvm/lib
parent96cfb9c65507df35539c880253a55800ee2a07cd (diff)
downloadbcm5719-llvm-d1fb13ce4c6b6563d1c725c06400e51d1d38983f.tar.gz
bcm5719-llvm-d1fb13ce4c6b6563d1c725c06400e51d1d38983f.zip
Fix crashes in IRCE caused by mismatched types
There are places where the inductive range check elimination pass depends on two llvm::Values or llvm::SCEVs to be of the same llvm::Type when they do not need to be. This patch relaxes those restrictions (by bailing out of the optimization if the types mismatch), and adds test cases to trigger those paths. These issues were found by bootstrapping clang with IRCE running in the -O3 pass ordering. Differential Revision: http://reviews.llvm.org/D7082 llvm-svn: 226793
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp42
1 files changed, 35 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp b/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
index 53115a9a12e..be62e4c745c 100644
--- a/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
@@ -489,8 +489,9 @@ class LoopConstrainer {
// Compute a safe set of limits for the main loop to run in -- effectively the
// intersection of `Range' and the iteration space of the original loop.
// Return the header count (1 + the latch taken count) in `HeaderCount'.
+ // Return None if unable to compute the set of subranges.
//
- SubRanges calculateSubRanges(Value *&HeaderCount) const;
+ Optional<SubRanges> calculateSubRanges(Value *&HeaderCount) const;
// Clone `OriginalLoop' and return the result in CLResult. The IR after
// running `cloneLoop' is well formed except for the PHI nodes in CLResult --
@@ -660,8 +661,14 @@ bool LoopConstrainer::recognizeLoop(LoopStructure &LoopStructureOut,
return false;
}
+ // IndVarSimplify will sometimes leave behind (in SCEV's cache) backedge-taken
+ // counts that are narrower than the canonical induction variable. These
+ // values are still accurate, and we could probably use them after sign/zero
+ // extension; but for now we just bail out of the transformation to keep
+ // things simple.
const SCEV *CIVComparedToSCEV = SE.getSCEV(CIVComparedTo);
- if (isa<SCEVCouldNotCompute>(CIVComparedToSCEV)) {
+ if (isa<SCEVCouldNotCompute>(CIVComparedToSCEV) ||
+ CIVComparedToSCEV->getType() != LatchCount->getType()) {
FailureReason = "could not relate CIV to latch expression";
return false;
}
@@ -699,10 +706,15 @@ bool LoopConstrainer::recognizeLoop(LoopStructure &LoopStructureOut,
return true;
}
-LoopConstrainer::SubRanges
+Optional<LoopConstrainer::SubRanges>
LoopConstrainer::calculateSubRanges(Value *&HeaderCountOut) const {
IntegerType *Ty = cast<IntegerType>(LatchTakenCount->getType());
+ assert(Range.first->getType() == Range.second->getType() &&
+ "ill-typed range!");
+ if (Range.first->getType() != Ty)
+ return None;
+
SCEVExpander Expander(SE, "irce");
Instruction *InsertPt = OriginalPreheader->getTerminator();
@@ -999,7 +1011,12 @@ bool LoopConstrainer::run() {
OriginalPreheader = Preheader;
MainLoopPreheader = Preheader;
- SubRanges SR = calculateSubRanges(OriginalHeaderCount);
+ Optional<SubRanges> MaybeSR = calculateSubRanges(OriginalHeaderCount);
+ if (!MaybeSR.hasValue()) {
+ DEBUG(dbgs() << "irce: could not compute subranges\n");
+ return false;
+ }
+ SubRanges SR = MaybeSR.getValue();
// It would have been better to make `PreLoop' and `PostLoop'
// `Optional<ClonedLoop>'s, but `ValueToValueMapTy' does not have a copy
@@ -1113,13 +1130,20 @@ InductiveRangeCheck::computeSafeIterationSpace(ScalarEvolution &SE,
return std::make_pair(Begin, End);
}
-static InductiveRangeCheck::Range
+static Optional<InductiveRangeCheck::Range>
IntersectRange(const Optional<InductiveRangeCheck::Range> &R1,
const InductiveRangeCheck::Range &R2, IRBuilder<> &B) {
+ assert(R2.first->getType() == R2.second->getType() && "ill-typed range!");
+
if (!R1.hasValue())
return R2;
auto &R1Value = R1.getValue();
+ // TODO: we could widen the smaller range and have this work; but for now we
+ // bail out to keep things simple.
+ if (R1Value.first->getType() != R2.first->getType())
+ return None;
+
Value *NewMin = ConstructSMaxOf(R1Value.first, R2.first, B);
Value *NewMax = ConstructSMinOf(R1Value.second, R2.second, B);
return std::make_pair(NewMin, NewMax);
@@ -1167,8 +1191,12 @@ bool InductiveRangeCheckElimination::runOnLoop(Loop *L, LPPassManager &LPM) {
for (InductiveRangeCheck *IRC : RangeChecks) {
auto Result = IRC->computeSafeIterationSpace(SE, B);
if (Result.hasValue()) {
- SafeIterRange = IntersectRange(SafeIterRange, Result.getValue(), B);
- RangeChecksToEliminate.push_back(IRC);
+ auto MaybeSafeIterRange =
+ IntersectRange(SafeIterRange, Result.getValue(), B);
+ if (MaybeSafeIterRange.hasValue()) {
+ RangeChecksToEliminate.push_back(IRC);
+ SafeIterRange = MaybeSafeIterRange.getValue();
+ }
}
}
OpenPOWER on IntegriCloud