Index: llvm/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/lib/Analysis/ScalarEvolution.cpp +++ llvm/lib/Analysis/ScalarEvolution.cpp @@ -5654,11 +5654,24 @@ 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 = APInt(BitWidth, 0); + if (SignHint == ScalarEvolution::HINT_RANGE_UNSIGNED) + UnsignedMinValue = getUnsignedRangeMin(AddRec->getStart()); + else { + ConstantRange StartRange = + getRangeRef(AddRec->getStart(), HINT_RANGE_SIGNED) + .intersectWith( + ConstantRange(APInt(BitWidth, 0), + APInt::getSignedMaxValue(BitWidth) + 1), + ConstantRange::Unsigned); + if (!StartRange.isEmptySet()) + UnsignedMinValue = StartRange.getUnsignedMin(); + } + if (!UnsignedMinValue.isNullValue()) + ConservativeResult = ConservativeResult.intersectWith( + ConstantRange(UnsignedMinValue, 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: [11,0) define void @test-addrec-nuw(float* %input, i32 %offset, i32 %numIterations) { entry: %cmp = icmp sgt i32 %offset, 10 Index: llvm/test/Transforms/IndVarSimplify/lftr-pr31181.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/lftr-pr31181.ll +++ llvm/test/Transforms/IndVarSimplify/lftr-pr31181.ll @@ -286,7 +286,7 @@ ; CHECK-NEXT: store volatile i32 [[IV2]], i32* [[PTR]] ; CHECK-NEXT: br label [[ALWAYS_TAKEN]] ; CHECK: always_taken: -; CHECK-NEXT: [[IV2_INC]] = add nuw nsw i32 [[IV2]], 1 +; CHECK-NEXT: [[IV2_INC]] = add nuw i32 [[IV2]], 1 ; CHECK-NEXT: [[IV_INC]] = add nsw i32 [[IV]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV2_INC]], -2147483628 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND]], label [[FOR_END:%.*]] @@ -329,7 +329,7 @@ ; CHECK-NEXT: store volatile i32 [[IV2]], i32* [[PTR]] ; CHECK-NEXT: br label [[ALWAYS_TAKEN]] ; CHECK: always_taken: -; CHECK-NEXT: [[IV2_INC]] = add nsw i32 [[IV2]], 1 +; CHECK-NEXT: [[IV2_INC]] = add i32 [[IV2]], 1 ; CHECK-NEXT: [[IV_INC]] = add nsw i32 [[IV]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV2_INC]], -2147483629 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND]], label [[FOR_END:%.*]]