Index: llvm/trunk/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp @@ -5596,6 +5596,14 @@ ConservativeResult.intersectWith(X, RangeType)); } + if (const SCEVUMinExpr *UMin = dyn_cast(S)) { + ConstantRange X = getRangeRef(UMin->getOperand(0), SignHint); + for (unsigned i = 1, e = UMin->getNumOperands(); i != e; ++i) + X = X.umin(getRangeRef(UMin->getOperand(i), SignHint)); + return setRange(UMin, SignHint, + ConservativeResult.intersectWith(X, RangeType)); + } + if (const SCEVUDivExpr *UDiv = dyn_cast(S)) { ConstantRange X = getRangeRef(UDiv->getLHS(), SignHint); ConstantRange Y = getRangeRef(UDiv->getRHS(), SignHint); Index: llvm/trunk/test/Analysis/ScalarEvolution/max-expr-cache.ll =================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/max-expr-cache.ll +++ llvm/trunk/test/Analysis/ScalarEvolution/max-expr-cache.ll @@ -130,7 +130,7 @@ %tmp45 = icmp ult i32 %tmp43, 256 %tmp46 = select i1 %tmp45, i32 %tmp43, i32 256 ; CHECK: %tmp46 = select i1 %tmp45, i32 %tmp43, i32 256 -; CHECK-NEXT: --> (256 umin (1 + (256 umin (1 + (256 umin (1 + (256 umin (1 + (256 umin (1 + (256 umin (1 + (256 umin (1 + (256 umin {%tmp3,+,-256}<%bb4>)) umin {%tmp3,+,-256}<%bb4>)) umin {%tmp3,+,-256}<%bb4>)) umin {%tmp3,+,-256}<%bb4>)) umin {%tmp3,+,-256}<%bb4>)) umin {%tmp3,+,-256}<%bb4>)) umin {%tmp3,+,-256}<%bb4>)) umin {%tmp3,+,-256}<%bb4>) +; CHECK-NEXT: --> (256 umin (1 + (256 umin (1 + (256 umin (1 + (256 umin (1 + (256 umin (1 + (256 umin (1 + (256 umin (1 + (256 umin {%tmp3,+,-256}<%bb4>)) umin {%tmp3,+,-256}<%bb4>)) umin {%tmp3,+,-256}<%bb4>)) umin {%tmp3,+,-256}<%bb4>)) umin {%tmp3,+,-256}<%bb4>)) umin {%tmp3,+,-256}<%bb4>)) umin {%tmp3,+,-256}<%bb4>)) umin {%tmp3,+,-256}<%bb4>) U: [0,257) S: [0,257) Exits: <> LoopDispositions: { %bb4: Computable, %bb53: Invariant } %tmp47 = icmp ugt i32 %tmp44, %tmp46 %tmp48 = select i1 %tmp47, i32 %tmp44, i32 %tmp46 %tmp49 = ashr i32 %tmp48, 3 Index: llvm/trunk/test/Analysis/ScalarEvolution/trip-count15.ll =================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/trip-count15.ll +++ llvm/trunk/test/Analysis/ScalarEvolution/trip-count15.ll @@ -5,15 +5,15 @@ ; CHECK-LABEL: 'umin_unsigned_check' ; CHECK-NEXT: Classifying expressions for: @umin_unsigned_check ; CHECK-NEXT: %min.n = select i1 %min.cmp, i64 4096, i64 %n -; CHECK-NEXT: --> (4096 umin %n) U: full-set S: full-set +; CHECK-NEXT: --> (4096 umin %n) U: [0,4097) S: [0,4097) ; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,4098) S: [0,4098) Exits: (1 + (4096 umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.next = add i64 %iv, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,4099) S: [1,4099) Exits: (2 + (4096 umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: Determining loop execution counts for: @umin_unsigned_check -; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count. -; CHECK-NEXT: Loop %loop: Unpredictable max backedge-taken count. -; CHECK-NEXT: Loop %loop: Unpredictable predicated backedge-taken count. +; CHECK-NEXT: Loop %loop: backedge-taken count is (1 + (4096 umin %n)) +; CHECK-NEXT: Loop %loop: max backedge-taken count is 4097 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (1 + (4096 umin %n)) ; entry: %min.cmp = icmp ult i64 4096, %n @@ -33,15 +33,15 @@ ; CHECK-LABEL: 'umin_signed_check' ; CHECK-NEXT: Classifying expressions for: @umin_signed_check ; CHECK-NEXT: %min.n = select i1 %min.cmp, i64 4096, i64 %n -; CHECK-NEXT: --> (4096 umin %n) U: full-set S: full-set +; CHECK-NEXT: --> (4096 umin %n) U: [0,4097) S: [0,4097) ; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,4098) S: [0,4098) Exits: (1 + (4096 umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.next = add i64 %iv, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,4099) S: [1,4099) Exits: (2 + (4096 umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: Determining loop execution counts for: @umin_signed_check -; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count. -; CHECK-NEXT: Loop %loop: Unpredictable max backedge-taken count. -; CHECK-NEXT: Loop %loop: Unpredictable predicated backedge-taken count. +; CHECK-NEXT: Loop %loop: backedge-taken count is (1 + (4096 umin %n)) +; CHECK-NEXT: Loop %loop: max backedge-taken count is 4097 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (1 + (4096 umin %n)) ; entry: %min.cmp = icmp ult i64 4096, %n