Index: llvm/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/lib/Analysis/ScalarEvolution.cpp +++ llvm/lib/Analysis/ScalarEvolution.cpp @@ -5654,11 +5654,17 @@ if (const SCEVAddRecExpr *AddRec = dyn_cast(S)) { // If there's no unsigned wrap, the value will never be less than its // initial value. - if (AddRec->hasNoUnsignedWrap()) - if (const SCEVConstant *C = dyn_cast(AddRec->getStart())) - if (!C->getValue()->isZero()) - ConservativeResult = ConservativeResult.intersectWith( - ConstantRange(C->getAPInt(), APInt(BitWidth, 0)), RangeType); + if (AddRec->hasNoUnsignedWrap()) { + APInt MinValue = APInt(BitWidth, 0); + const SCEV *Start = AddRec->getStart(); + if (SignHint == ScalarEvolution::HINT_RANGE_UNSIGNED) + MinValue = getUnsignedRangeMin(AddRec->getStart()); + else if (isKnownNonNegative(Start) || isKnownNonPositive(Start)) + MinValue = getSignedRangeMin(Start); + if (!MinValue.isNullValue()) + ConservativeResult = ConservativeResult.intersectWith( + ConstantRange(MinValue, APInt(BitWidth, 0)), RangeType); + } // If there's no signed wrap, and all the operands have the same sign or // zero, the value won't ever change sign. Index: llvm/test/Analysis/ScalarEvolution/range_nw_flag.ll =================================================================== --- llvm/test/Analysis/ScalarEvolution/range_nw_flag.ll +++ llvm/test/Analysis/ScalarEvolution/range_nw_flag.ll @@ -20,7 +20,7 @@ } ; CHECK-LABEL: @test-addrec-nuw -; CHECK: --> {(1 + (10 smax %offset)),+,1}<%loop> U: full-set S: full-set +; CHECK: --> {(1 + (10 smax %offset)),+,1}<%loop> U: [11,0) S: full-set define void @test-addrec-nuw(float* %input, i32 %offset, i32 %numIterations) { entry: %cmp = icmp sgt i32 %offset, 10