@@ -489,8 +489,9 @@ class LoopConstrainer {
489
489
// Compute a safe set of limits for the main loop to run in -- effectively the
490
490
// intersection of `Range' and the iteration space of the original loop.
491
491
// Return the header count (1 + the latch taken count) in `HeaderCount'.
492
+ // Return None if unable to compute the set of subranges.
492
493
//
493
- SubRanges calculateSubRanges (Value *&HeaderCount) const ;
494
+ Optional< SubRanges> calculateSubRanges (Value *&HeaderCount) const ;
494
495
495
496
// Clone `OriginalLoop' and return the result in CLResult. The IR after
496
497
// running `cloneLoop' is well formed except for the PHI nodes in CLResult --
@@ -660,8 +661,14 @@ bool LoopConstrainer::recognizeLoop(LoopStructure &LoopStructureOut,
660
661
return false ;
661
662
}
662
663
664
+ // IndVarSimplify will sometimes leave behind (in SCEV's cache) backedge-taken
665
+ // counts that are narrower than the canonical induction variable. These
666
+ // values are still accurate, and we could probably use them after sign/zero
667
+ // extension; but for now we just bail out of the transformation to keep
668
+ // things simple.
663
669
const SCEV *CIVComparedToSCEV = SE.getSCEV (CIVComparedTo);
664
- if (isa<SCEVCouldNotCompute>(CIVComparedToSCEV)) {
670
+ if (isa<SCEVCouldNotCompute>(CIVComparedToSCEV) ||
671
+ CIVComparedToSCEV->getType () != LatchCount->getType ()) {
665
672
FailureReason = " could not relate CIV to latch expression" ;
666
673
return false ;
667
674
}
@@ -699,10 +706,15 @@ bool LoopConstrainer::recognizeLoop(LoopStructure &LoopStructureOut,
699
706
return true ;
700
707
}
701
708
702
- LoopConstrainer::SubRanges
709
+ Optional< LoopConstrainer::SubRanges>
703
710
LoopConstrainer::calculateSubRanges (Value *&HeaderCountOut) const {
704
711
IntegerType *Ty = cast<IntegerType>(LatchTakenCount->getType ());
705
712
713
+ assert (Range.first ->getType () == Range.second ->getType () &&
714
+ " ill-typed range!" );
715
+ if (Range.first ->getType () != Ty)
716
+ return None;
717
+
706
718
SCEVExpander Expander (SE, " irce" );
707
719
Instruction *InsertPt = OriginalPreheader->getTerminator ();
708
720
@@ -999,7 +1011,12 @@ bool LoopConstrainer::run() {
999
1011
OriginalPreheader = Preheader;
1000
1012
MainLoopPreheader = Preheader;
1001
1013
1002
- SubRanges SR = calculateSubRanges (OriginalHeaderCount);
1014
+ Optional<SubRanges> MaybeSR = calculateSubRanges (OriginalHeaderCount);
1015
+ if (!MaybeSR.hasValue ()) {
1016
+ DEBUG (dbgs () << " irce: could not compute subranges\n " );
1017
+ return false ;
1018
+ }
1019
+ SubRanges SR = MaybeSR.getValue ();
1003
1020
1004
1021
// It would have been better to make `PreLoop' and `PostLoop'
1005
1022
// `Optional<ClonedLoop>'s, but `ValueToValueMapTy' does not have a copy
@@ -1113,13 +1130,20 @@ InductiveRangeCheck::computeSafeIterationSpace(ScalarEvolution &SE,
1113
1130
return std::make_pair (Begin, End);
1114
1131
}
1115
1132
1116
- static InductiveRangeCheck::Range
1133
+ static Optional< InductiveRangeCheck::Range>
1117
1134
IntersectRange (const Optional<InductiveRangeCheck::Range> &R1,
1118
1135
const InductiveRangeCheck::Range &R2, IRBuilder<> &B) {
1136
+ assert (R2.first ->getType () == R2.second ->getType () && " ill-typed range!" );
1137
+
1119
1138
if (!R1.hasValue ())
1120
1139
return R2;
1121
1140
auto &R1Value = R1.getValue ();
1122
1141
1142
+ // TODO: we could widen the smaller range and have this work; but for now we
1143
+ // bail out to keep things simple.
1144
+ if (R1Value.first ->getType () != R2.first ->getType ())
1145
+ return None;
1146
+
1123
1147
Value *NewMin = ConstructSMaxOf (R1Value.first , R2.first , B);
1124
1148
Value *NewMax = ConstructSMinOf (R1Value.second , R2.second , B);
1125
1149
return std::make_pair (NewMin, NewMax);
@@ -1167,8 +1191,12 @@ bool InductiveRangeCheckElimination::runOnLoop(Loop *L, LPPassManager &LPM) {
1167
1191
for (InductiveRangeCheck *IRC : RangeChecks) {
1168
1192
auto Result = IRC->computeSafeIterationSpace (SE, B);
1169
1193
if (Result.hasValue ()) {
1170
- SafeIterRange = IntersectRange (SafeIterRange, Result.getValue (), B);
1171
- RangeChecksToEliminate.push_back (IRC);
1194
+ auto MaybeSafeIterRange =
1195
+ IntersectRange (SafeIterRange, Result.getValue (), B);
1196
+ if (MaybeSafeIterRange.hasValue ()) {
1197
+ RangeChecksToEliminate.push_back (IRC);
1198
+ SafeIterRange = MaybeSafeIterRange.getValue ();
1199
+ }
1172
1200
}
1173
1201
}
1174
1202
0 commit comments