Index: llvm/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/lib/Analysis/ScalarEvolution.cpp +++ llvm/lib/Analysis/ScalarEvolution.cpp @@ -8957,6 +8957,7 @@ const SCEV *BECount = getCouldNotCompute(); const SCEV *ConstantMaxBECount = getCouldNotCompute(); + const SCEV *SymbolicMaxBECount = getCouldNotCompute(); if (EitherMayExit) { // Both conditions must be same for the loop to continue executing. // Choose the less conservative count. @@ -8973,6 +8974,14 @@ else ConstantMaxBECount = getUMinFromMismatchedTypes(EL0.ConstantMaxNotTaken, EL1.ConstantMaxNotTaken); + if (EL0.SymbolicMaxNotTaken == getCouldNotCompute()) + SymbolicMaxBECount = EL1.SymbolicMaxNotTaken; + else if (EL1.SymbolicMaxNotTaken == getCouldNotCompute()) + SymbolicMaxBECount = EL0.SymbolicMaxNotTaken; + else + SymbolicMaxBECount = getUMinFromMismatchedTypes(EL0.SymbolicMaxNotTaken, + EL1.SymbolicMaxNotTaken, + /*Sequential*/ true); } else { // Both conditions must be same at the same time for the loop to exit. // For now, be conservative. @@ -8989,8 +8998,9 @@ if (isa(ConstantMaxBECount) && !isa(BECount)) ConstantMaxBECount = getConstant(getUnsignedRangeMax(BECount)); - const SCEV *SymbolicMaxBECount = - isa(BECount) ? ConstantMaxBECount : BECount; + if (isa(SymbolicMaxBECount)) + SymbolicMaxBECount = + isa(BECount) ? ConstantMaxBECount : BECount; return ExitLimit(BECount, ConstantMaxBECount, SymbolicMaxBECount, false, { &EL0.Predicates, &EL1.Predicates }); } Index: llvm/test/Analysis/ScalarEvolution/symbolic_max_exit_count.ll =================================================================== --- llvm/test/Analysis/ScalarEvolution/symbolic_max_exit_count.ll +++ llvm/test/Analysis/ScalarEvolution/symbolic_max_exit_count.ll @@ -54,7 +54,6 @@ ret i32 -2 } -; TODO: Symbolic max can be %start define i32 @test_litter_conditions(i32 %start, i32 %len) { ; CHECK-LABEL: 'test_litter_conditions' ; CHECK-NEXT: Classifying expressions for: @test_litter_conditions @@ -80,8 +79,8 @@ ; CHECK-NEXT: exit count for range_check_block: ***COULDNOTCOMPUTE*** ; CHECK-NEXT: exit count for backedge: ***COULDNOTCOMPUTE*** ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is -1 -; CHECK-NEXT: symbolic max exit count for loop: -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %start +; CHECK-NEXT: symbolic max exit count for loop: %start ; CHECK-NEXT: symbolic max exit count for range_check_block: ***COULDNOTCOMPUTE*** ; CHECK-NEXT: symbolic max exit count for backedge: ***COULDNOTCOMPUTE*** ; CHECK-NEXT: Loop %loop: Unpredictable predicated backedge-taken count. @@ -118,7 +117,6 @@ ret i32 -2 } -; TODO: Symbolic max can be %start define i32 @test_litter_conditions_bad_context(i32 %start, i32 %len) { ; CHECK-LABEL: 'test_litter_conditions_bad_context' ; CHECK-NEXT: Classifying expressions for: @test_litter_conditions_bad_context @@ -144,8 +142,8 @@ ; CHECK-NEXT: exit count for range_check_block: ***COULDNOTCOMPUTE*** ; CHECK-NEXT: exit count for backedge: ***COULDNOTCOMPUTE*** ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is -1 -; CHECK-NEXT: symbolic max exit count for loop: -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %start +; CHECK-NEXT: symbolic max exit count for loop: %start ; CHECK-NEXT: symbolic max exit count for range_check_block: ***COULDNOTCOMPUTE*** ; CHECK-NEXT: symbolic max exit count for backedge: ***COULDNOTCOMPUTE*** ; CHECK-NEXT: Loop %loop: Unpredictable predicated backedge-taken count. @@ -182,7 +180,6 @@ ret i32 -2 } -; TODO: Symbolic max can be %start define i32 @test_and_conditions(i32 %start, i32 %len) { ; CHECK-LABEL: 'test_and_conditions' ; CHECK-NEXT: Classifying expressions for: @test_and_conditions @@ -201,8 +198,8 @@ ; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE*** ; CHECK-NEXT: exit count for backedge: ***COULDNOTCOMPUTE*** ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is -1 -; CHECK-NEXT: symbolic max exit count for loop: -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %start +; CHECK-NEXT: symbolic max exit count for loop: %start ; CHECK-NEXT: symbolic max exit count for backedge: ***COULDNOTCOMPUTE*** ; CHECK-NEXT: Loop %loop: Unpredictable predicated backedge-taken count. ;