diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -5672,11 +5672,12 @@ 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 UnsignedMinValue = getUnsignedRangeMin(AddRec->getStart()); + if (!UnsignedMinValue.isNullValue()) + ConservativeResult = ConservativeResult.intersectWith( + ConstantRange(UnsignedMinValue, APInt(BitWidth, 0)), RangeType); + } // If there's no signed wrap, and all the operands except initial value have // the same sign or zero, the value won't ever be: diff --git a/llvm/test/Analysis/ScalarEvolution/range_nw_flag.ll b/llvm/test/Analysis/ScalarEvolution/range_nw_flag.ll --- a/llvm/test/Analysis/ScalarEvolution/range_nw_flag.ll +++ b/llvm/test/Analysis/ScalarEvolution/range_nw_flag.ll @@ -2,7 +2,7 @@ ; copied from flags-from-poison.ll ; CHECK-LABEL: @test-add-nuw -; CHECK: --> {(1 + %offset),+,1}<%loop> U: full-set S: full-set +; CHECK: --> {(1 + %offset),+,1}<%loop> U: [1,0) S: [1,0) define void @test-add-nuw(float* %input, i32 %offset, i32 %numIterations) { entry: br label %loop @@ -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: [11,0) define void @test-addrec-nuw(float* %input, i32 %offset, i32 %numIterations) { entry: %cmp = icmp sgt i32 %offset, 10