@@ -193,17 +193,19 @@ RuntimeCheckingPtrGroup::RuntimeCheckingPtrGroup(
193193// / Returns \p A + \p B, if it is guaranteed not to unsigned wrap. Otherwise
194194// / return nullptr. \p A and \p B must have the same type.
195195static const SCEV *addSCEVNoOverflow (const SCEV *A, const SCEV *B,
196- ScalarEvolution &SE) {
197- if (!SE.willNotOverflow (Instruction::Add, /* IsSigned=*/ false , A, B))
196+ ScalarEvolution &SE,
197+ const Instruction *CtxI) {
198+ if (!SE.willNotOverflow (Instruction::Add, /* IsSigned=*/ false , A, B, CtxI))
198199 return nullptr ;
199200 return SE.getAddExpr (A, B);
200201}
201202
202203// / Returns \p A * \p B, if it is guaranteed not to unsigned wrap. Otherwise
203204// / return nullptr. \p A and \p B must have the same type.
204205static const SCEV *mulSCEVOverflow (const SCEV *A, const SCEV *B,
205- ScalarEvolution &SE) {
206- if (!SE.willNotOverflow (Instruction::Mul, /* IsSigned=*/ false , A, B))
206+ ScalarEvolution &SE,
207+ const Instruction *CtxI) {
208+ if (!SE.willNotOverflow (Instruction::Mul, /* IsSigned=*/ false , A, B, CtxI))
207209 return nullptr ;
208210 return SE.getMulExpr (A, B);
209211}
@@ -232,11 +234,12 @@ evaluatePtrAddRecAtMaxBTCWillNotWrap(const SCEVAddRecExpr *AR,
232234 Type *WiderTy = SE.getWiderType (MaxBTC->getType (), Step->getType ());
233235 const SCEV *DerefBytesSCEV = SE.getConstant (WiderTy, DerefBytes);
234236
237+ // Context which dominates the entire loop.
238+ auto *CtxI = L->getLoopPredecessor ()->getTerminator ();
235239 // Check if we have a suitable dereferencable assumption we can use.
236240 if (!StartPtrV->canBeFreed ()) {
237241 RetainedKnowledge DerefRK = getKnowledgeValidInContext (
238- StartPtrV, {Attribute::Dereferenceable}, *AC,
239- L->getLoopPredecessor ()->getTerminator (), DT);
242+ StartPtrV, {Attribute::Dereferenceable}, *AC, CtxI, DT);
240243 if (DerefRK) {
241244 DerefBytesSCEV = SE.getUMaxExpr (
242245 DerefBytesSCEV, SE.getConstant (WiderTy, DerefRK.ArgValue ));
@@ -260,20 +263,21 @@ evaluatePtrAddRecAtMaxBTCWillNotWrap(const SCEVAddRecExpr *AR,
260263 SE.getMinusSCEV (AR->getStart (), StartPtr), WiderTy);
261264
262265 const SCEV *OffsetAtLastIter =
263- mulSCEVOverflow (MaxBTC, SE.getAbsExpr (Step, /* IsNSW=*/ false ), SE);
266+ mulSCEVOverflow (MaxBTC, SE.getAbsExpr (Step, /* IsNSW=*/ false ), SE, CtxI );
264267 if (!OffsetAtLastIter)
265268 return false ;
266269
267270 const SCEV *OffsetEndBytes = addSCEVNoOverflow (
268- OffsetAtLastIter, SE.getNoopOrZeroExtend (EltSize, WiderTy), SE);
271+ OffsetAtLastIter, SE.getNoopOrZeroExtend (EltSize, WiderTy), SE, CtxI );
269272 if (!OffsetEndBytes)
270273 return false ;
271274
272275 if (IsKnownNonNegative) {
273276 // For positive steps, check if
274277 // (AR->getStart() - StartPtr) + (MaxBTC * Step) + EltSize <= DerefBytes,
275278 // while making sure none of the computations unsigned wrap themselves.
276- const SCEV *EndBytes = addSCEVNoOverflow (StartOffset, OffsetEndBytes, SE);
279+ const SCEV *EndBytes =
280+ addSCEVNoOverflow (StartOffset, OffsetEndBytes, SE, CtxI);
277281 if (!EndBytes)
278282 return false ;
279283 return SE.isKnownPredicate (CmpInst::ICMP_ULE, EndBytes, DerefBytesSCEV);
0 commit comments