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 @@ -14548,6 +14548,22 @@ LoopEntryPredicate->getSuccessor(0) == Pair.second); } + // Sort conditions so that conditions that tighten ranges of values come last. + // This allows processing them first in the loop below, which can lead to more + // effective expression rewriting. + stable_sort(Terms, [this](const std::pair &A, + const std::pair &B) { + auto *CmpA = dyn_cast(A.first); + auto *CmpB = dyn_cast(B.first); + if (!CmpA || !CmpB) + return false; + bool IsRangeA = CmpA->getPredicate() != CmpInst::ICMP_NE && + CmpA->getPredicate() != CmpInst::ICMP_EQ; + bool IsRangeB = CmpB->getPredicate() != CmpInst::ICMP_NE && + CmpB->getPredicate() != CmpInst::ICMP_EQ; + return IsRangeA < IsRangeB; + }); + // Now apply the information from the collected conditions to RewriteMap. // Conditions are processed in reverse order, so the earliest conditions is // processed first. This ensures the SCEVs with the shortest dependency chains diff --git a/llvm/test/Analysis/ScalarEvolution/trip-multiple-guard-info.ll b/llvm/test/Analysis/ScalarEvolution/trip-multiple-guard-info.ll --- a/llvm/test/Analysis/ScalarEvolution/trip-multiple-guard-info.ll +++ b/llvm/test/Analysis/ScalarEvolution/trip-multiple-guard-info.ll @@ -34,7 +34,7 @@ ; CHECK: Loop %for.body: backedge-taken count is (-1 + %num) ; CHECK-NEXT: Loop %for.body: max backedge-taken count is -2 ; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (-1 + %num) -; CHECK: Loop %for.body: Trip multiple is 2 +; CHECK: Loop %for.body: Trip multiple is 4 ; entry: %u = urem i32 %num, 4 @@ -59,7 +59,7 @@ ; CHECK: Loop %for.body: backedge-taken count is (-1 + %num) ; CHECK-NEXT: Loop %for.body: max backedge-taken count is 2147483646 ; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (-1 + %num) -; CHECK: Loop %for.body: Trip multiple is 2 +; CHECK: Loop %for.body: Trip multiple is 4 ; entry: %u = urem i32 %num, 4 @@ -84,7 +84,7 @@ ; CHECK: Loop %for.body: backedge-taken count is (-1 + %num) ; CHECK-NEXT: Loop %for.body: max backedge-taken count is -2 ; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (-1 + %num) -; CHECK: Loop %for.body: Trip multiple is 1 +; CHECK: Loop %for.body: Trip multiple is 4 ; entry: %u = urem i32 %num, 4 @@ -104,12 +104,37 @@ ret void } +define void @test_trip_multiple_4_uge_5_order_swapped(i32 %num) { +; CHECK-LABEL: @test_trip_multiple_4_uge_5_order_swapped +; CHECK: Loop %for.body: backedge-taken count is (-1 + %num) +; CHECK-NEXT: Loop %for.body: max backedge-taken count is -2 +; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (-1 + %num) +; CHECK: Loop %for.body: Trip multiple is 4 +; +entry: + %u = urem i32 %num, 4 + %cmp = icmp eq i32 %u, 0 + %cmp.1 = icmp uge i32 %num, 5 + tail call void @llvm.assume(i1 %cmp.1) + tail call void @llvm.assume(i1 %cmp) + br label %for.body + +for.body: + %i.010 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %inc = add nuw nsw i32 %i.010, 1 + %cmp2 = icmp ult i32 %inc, %num + br i1 %cmp2, label %for.body, label %exit + +exit: + ret void +} + define void @test_trip_multiple_4_sge_5(i32 %num) { ; CHECK-LABEL: @test_trip_multiple_4_sge_5 ; CHECK: Loop %for.body: backedge-taken count is (-1 + %num) ; CHECK-NEXT: Loop %for.body: max backedge-taken count is 2147483646 ; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (-1 + %num) -; CHECK: Loop %for.body: Trip multiple is 1 +; CHECK: Loop %for.body: Trip multiple is 4 ; entry: %u = urem i32 %num, 4