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 @@ -8961,14 +8961,15 @@ const SCEV *BECount = getCouldNotCompute(); const SCEV *ConstantMaxBECount = getCouldNotCompute(); + const SCEV *SymbolicMaxBECount = getCouldNotCompute(); if (EitherMayExit) { + bool UseSequentialUMin = !isa(ExitCond); // Both conditions must be same for the loop to continue executing. // Choose the less conservative count. if (EL0.ExactNotTaken != getCouldNotCompute() && EL1.ExactNotTaken != getCouldNotCompute()) { - BECount = getUMinFromMismatchedTypes( - EL0.ExactNotTaken, EL1.ExactNotTaken, - /*Sequential=*/!isa(ExitCond)); + BECount = getUMinFromMismatchedTypes(EL0.ExactNotTaken, EL1.ExactNotTaken, + UseSequentialUMin); } if (EL0.ConstantMaxNotTaken == getCouldNotCompute()) ConstantMaxBECount = EL1.ConstantMaxNotTaken; @@ -8977,6 +8978,13 @@ 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, UseSequentialUMin); } else { // Both conditions must be same at the same time for the loop to exit. // For now, be conservative. @@ -8993,8 +9001,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 }); } diff --git a/llvm/test/Analysis/ScalarEvolution/symbolic_max_exit_count.ll b/llvm/test/Analysis/ScalarEvolution/symbolic_max_exit_count.ll --- a/llvm/test/Analysis/ScalarEvolution/symbolic_max_exit_count.ll +++ b/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. ; @@ -320,7 +317,6 @@ ret i32 -1 } -; TODO: Symbolic max can be start1 umin_seq start2 define i32 @test_two_phis(i32 %start_1, i32 %start_2, i32 %len) { ; CHECK-LABEL: 'test_two_phis' ; CHECK-NEXT: Classifying expressions for: @test_two_phis @@ -351,9 +347,9 @@ ; 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: symbolic max exit count for zero_check_block: -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%start_1 umin_seq %start_2) +; CHECK-NEXT: symbolic max exit count for loop: %start_1 +; CHECK-NEXT: symbolic max exit count for zero_check_block: %start_2 ; 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. @@ -438,7 +434,6 @@ ret i32 0 } -; TODO: Symbolic max can be start1 umin start2 define i32 @test_two_phis_arithmetic_and(i32 %start_1, i32 %start_2, i32 %len) { ; CHECK-LABEL: 'test_two_phis_arithmetic_and' ; CHECK-NEXT: Classifying expressions for: @test_two_phis_arithmetic_and @@ -470,8 +465,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_1 umin %start_2) +; CHECK-NEXT: symbolic max exit count for loop: (%start_1 umin %start_2) ; 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. @@ -586,7 +581,6 @@ ret i32 -2 } -; TODO: Symbolic max can be start1 umin_seq start2 define i32 @test_two_phis_logical_and(i32 %start_1, i32 %start_2, i32 %len) { ; CHECK-LABEL: 'test_two_phis_logical_and' ; CHECK-NEXT: Classifying expressions for: @test_two_phis_logical_and @@ -618,8 +612,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_1 umin_seq %start_2) +; CHECK-NEXT: symbolic max exit count for loop: (%start_1 umin_seq %start_2) ; 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.