| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --filter "br " --filter "^.*:" --version 6 | |
| ; RUN: opt -passes=loop-unroll -unroll-runtime -S %s | FileCheck %s | |
| ; RUN: opt -passes=loop-unroll -unroll-runtime -unroll-count=4 -S %s | FileCheck %s -check-prefix=FORCED | |
| ; Check how loops with estimated trip counts of 0 are handled. | |
| ; Test where latch weights on their own would estimate a trip count of 1024; | |
| ; the explicit llvm.loop.estimated_trip_count of 0 takes precedence. | |
| define void @zero_estimated_trip_count(ptr %p, i64 %n) !prof !0 { | |
| ; CHECK-LABEL: define void @zero_estimated_trip_count( | |
| ; CHECK-SAME: ptr [[P:%.*]], i64 [[N:%.*]]) !prof [[PROF0:![0-9]+]] { | |
| ; CHECK: [[ENTRY:.*:]] | |
| ; CHECK: br label %[[LOOP:.*]] | |
| ; CHECK: [[LOOP]]: | |
| ; CHECK: br i1 [[CMP_LOOP:%.*]], label %[[EXIT:.*]], label %[[LOOP]], !prof [[PROF1:![0-9]+]], !llvm.loop [[LOOP2:![0-9]+]] | |
| ; CHECK: [[EXIT]]: | |
| ; | |
| ; FORCED-LABEL: define void @zero_estimated_trip_count( | |
| ; FORCED-SAME: ptr [[P:%.*]], i64 [[N:%.*]]) !prof [[PROF0:![0-9]+]] { | |
| ; FORCED: [[ENTRY:.*:]] | |
| ; FORCED: br i1 [[TMP1:%.*]], label %[[LOOP_EPIL_PREHEADER:.*]], label %[[ENTRY_NEW:.*]], !prof [[PROF1:![0-9]+]] | |
| ; FORCED: [[ENTRY_NEW]]: | |
| ; FORCED: br label %[[LOOP:.*]] | |
| ; FORCED: [[LOOP]]: | |
| ; FORCED: br i1 [[NITER_NCMP_3:%.*]], label %[[EXIT_UNR_LCSSA:.*]], label %[[LOOP]], !prof [[PROF2:![0-9]+]], !llvm.loop [[LOOP3:![0-9]+]] | |
| ; FORCED: [[EXIT_UNR_LCSSA]]: | |
| ; FORCED: br i1 [[LCMP_MOD:%.*]], label %[[LOOP_EPIL_PREHEADER]], label %[[EXIT:.*]], !prof [[PROF6:![0-9]+]] | |
| ; FORCED: [[LOOP_EPIL_PREHEADER]]: | |
| ; FORCED: br label %[[LOOP_EPIL:.*]] | |
| ; FORCED: [[LOOP_EPIL]]: | |
| ; FORCED: br i1 [[EPIL_ITER_CMP:%.*]], label %[[LOOP_EPIL]], label %[[EXIT_EPILOG_LCSSA:.*]], !prof [[PROF7:![0-9]+]], !llvm.loop [[LOOP8:![0-9]+]] | |
| ; FORCED: [[EXIT_EPILOG_LCSSA]]: | |
| ; FORCED: br label %[[EXIT]] | |
| ; FORCED: [[EXIT]]: | |
| ; | |
| entry: | |
| br label %loop | |
| loop: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] | |
| %ptr = getelementptr inbounds i32, ptr %p, i64 %iv | |
| %v = load i32, ptr %ptr | |
| %add = add i32 %v, 1 | |
| store i32 %add, ptr %ptr | |
| %iv.next = add i64 %iv, 1 | |
| %cmp.loop = icmp eq i64 %iv.next, %n | |
| br i1 %cmp.loop, label %exit, label %loop, !prof !1, !llvm.loop !2 | |
| exit: | |
| ret void | |
| } | |
| ; Same loop but with a high estimated trip count, which is runtime unrolled. | |
| define void @high_estimated_trip_count(ptr %p, i64 %n) !prof !0 { | |
| ; CHECK-LABEL: define void @high_estimated_trip_count( | |
| ; CHECK-SAME: ptr [[P:%.*]], i64 [[N:%.*]]) !prof [[PROF0]] { | |
| ; CHECK: [[ENTRY:.*:]] | |
| ; CHECK: br i1 [[TMP1:%.*]], label %[[LOOP_EPIL_PREHEADER:.*]], label %[[ENTRY_NEW:.*]], !prof [[PROF4:![0-9]+]] | |
| ; CHECK: [[ENTRY_NEW]]: | |
| ; CHECK: br label %[[LOOP:.*]] | |
| ; CHECK: [[LOOP]]: | |
| ; CHECK: br i1 [[NITER_NCMP_7:%.*]], label %[[EXIT_UNR_LCSSA:.*]], label %[[LOOP]], !prof [[PROF5:![0-9]+]], !llvm.loop [[LOOP6:![0-9]+]] | |
| ; CHECK: [[EXIT_UNR_LCSSA]]: | |
| ; CHECK: br i1 [[LCMP_MOD:%.*]], label %[[LOOP_EPIL_PREHEADER]], label %[[EXIT:.*]], !prof [[PROF8:![0-9]+]] | |
| ; CHECK: [[LOOP_EPIL_PREHEADER]]: | |
| ; CHECK: br label %[[LOOP_EPIL:.*]] | |
| ; CHECK: [[LOOP_EPIL]]: | |
| ; CHECK: br i1 [[EPIL_ITER_CMP:%.*]], label %[[LOOP_EPIL]], label %[[EXIT_EPILOG_LCSSA:.*]], !prof [[PROF9:![0-9]+]], !llvm.loop [[LOOP10:![0-9]+]] | |
| ; CHECK: [[EXIT_EPILOG_LCSSA]]: | |
| ; CHECK: br label %[[EXIT]] | |
| ; CHECK: [[EXIT]]: | |
| ; | |
| ; FORCED-LABEL: define void @high_estimated_trip_count( | |
| ; FORCED-SAME: ptr [[P:%.*]], i64 [[N:%.*]]) !prof [[PROF0]] { | |
| ; FORCED: [[ENTRY:.*:]] | |
| ; FORCED: br i1 [[TMP1:%.*]], label %[[LOOP_EPIL_PREHEADER:.*]], label %[[ENTRY_NEW:.*]], !prof [[PROF1]] | |
| ; FORCED: [[ENTRY_NEW]]: | |
| ; FORCED: br label %[[LOOP:.*]] | |
| ; FORCED: [[LOOP]]: | |
| ; FORCED: br i1 [[NITER_NCMP_3:%.*]], label %[[EXIT_UNR_LCSSA:.*]], label %[[LOOP]], !prof [[PROF2]], !llvm.loop [[LOOP9:![0-9]+]] | |
| ; FORCED: [[EXIT_UNR_LCSSA]]: | |
| ; FORCED: br i1 [[LCMP_MOD:%.*]], label %[[LOOP_EPIL_PREHEADER]], label %[[EXIT:.*]], !prof [[PROF6]] | |
| ; FORCED: [[LOOP_EPIL_PREHEADER]]: | |
| ; FORCED: br label %[[LOOP_EPIL:.*]] | |
| ; FORCED: [[LOOP_EPIL]]: | |
| ; FORCED: br i1 [[EPIL_ITER_CMP:%.*]], label %[[LOOP_EPIL]], label %[[EXIT_EPILOG_LCSSA:.*]], !prof [[PROF7]], !llvm.loop [[LOOP11:![0-9]+]] | |
| ; FORCED: [[EXIT_EPILOG_LCSSA]]: | |
| ; FORCED: br label %[[EXIT]] | |
| ; FORCED: [[EXIT]]: | |
| ; | |
| entry: | |
| br label %loop | |
| loop: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] | |
| %ptr = getelementptr inbounds i32, ptr %p, i64 %iv | |
| %v = load i32, ptr %ptr | |
| %add = add i32 %v, 1 | |
| store i32 %add, ptr %ptr | |
| %iv.next = add i64 %iv, 1 | |
| %cmp.loop = icmp eq i64 %iv.next, %n | |
| br i1 %cmp.loop, label %exit, label %loop, !prof !1, !llvm.loop !3 | |
| exit: | |
| ret void | |
| } | |
| ; Loop with a high estimated trip count, but branch weights that almost always | |
| ; exit the loop. | |
| define void @high_estimated_trip_count_low_branch_weights(ptr %p, i64 %n) !prof !0 { | |
| ; CHECK-LABEL: define void @high_estimated_trip_count_low_branch_weights( | |
| ; CHECK-SAME: ptr [[P:%.*]], i64 [[N:%.*]]) !prof [[PROF0]] { | |
| ; CHECK: [[ENTRY:.*:]] | |
| ; CHECK: br i1 [[TMP1:%.*]], label %[[LOOP_EPIL_PREHEADER:.*]], label %[[ENTRY_NEW:.*]], !prof [[PROF12:![0-9]+]] | |
| ; CHECK: [[ENTRY_NEW]]: | |
| ; CHECK: br label %[[LOOP:.*]] | |
| ; CHECK: [[LOOP]]: | |
| ; CHECK: br i1 [[NITER_NCMP_7:%.*]], label %[[EXIT_UNR_LCSSA:.*]], label %[[LOOP]], !prof [[PROF12]], !llvm.loop [[LOOP13:![0-9]+]] | |
| ; CHECK: [[EXIT_UNR_LCSSA]]: | |
| ; CHECK: br i1 [[LCMP_MOD:%.*]], label %[[LOOP_EPIL_PREHEADER]], label %[[EXIT:.*]], !prof [[PROF14:![0-9]+]] | |
| ; CHECK: [[LOOP_EPIL_PREHEADER]]: | |
| ; CHECK: br label %[[LOOP_EPIL:.*]] | |
| ; CHECK: [[LOOP_EPIL]]: | |
| ; CHECK: br i1 [[EPIL_ITER_CMP:%.*]], label %[[LOOP_EPIL]], label %[[EXIT_EPILOG_LCSSA:.*]], !prof [[PROF14]], !llvm.loop [[LOOP15:![0-9]+]] | |
| ; CHECK: [[EXIT_EPILOG_LCSSA]]: | |
| ; CHECK: br label %[[EXIT]] | |
| ; CHECK: [[EXIT]]: | |
| ; | |
| ; FORCED-LABEL: define void @high_estimated_trip_count_low_branch_weights( | |
| ; FORCED-SAME: ptr [[P:%.*]], i64 [[N:%.*]]) !prof [[PROF0]] { | |
| ; FORCED: [[ENTRY:.*:]] | |
| ; FORCED: br i1 [[TMP1:%.*]], label %[[LOOP_EPIL_PREHEADER:.*]], label %[[ENTRY_NEW:.*]], !prof [[PROF12:![0-9]+]] | |
| ; FORCED: [[ENTRY_NEW]]: | |
| ; FORCED: br label %[[LOOP:.*]] | |
| ; FORCED: [[LOOP]]: | |
| ; FORCED: br i1 [[NITER_NCMP_3:%.*]], label %[[EXIT_UNR_LCSSA:.*]], label %[[LOOP]], !prof [[PROF13:![0-9]+]], !llvm.loop [[LOOP14:![0-9]+]] | |
| ; FORCED: [[EXIT_UNR_LCSSA]]: | |
| ; FORCED: br i1 [[LCMP_MOD:%.*]], label %[[LOOP_EPIL_PREHEADER]], label %[[EXIT:.*]], !prof [[PROF15:![0-9]+]] | |
| ; FORCED: [[LOOP_EPIL_PREHEADER]]: | |
| ; FORCED: br label %[[LOOP_EPIL:.*]] | |
| ; FORCED: [[LOOP_EPIL]]: | |
| ; FORCED: br i1 [[EPIL_ITER_CMP:%.*]], label %[[LOOP_EPIL]], label %[[EXIT_EPILOG_LCSSA:.*]], !prof [[PROF16:![0-9]+]], !llvm.loop [[LOOP17:![0-9]+]] | |
| ; FORCED: [[EXIT_EPILOG_LCSSA]]: | |
| ; FORCED: br label %[[EXIT]] | |
| ; FORCED: [[EXIT]]: | |
| ; | |
| entry: | |
| br label %loop | |
| loop: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] | |
| %ptr = getelementptr inbounds i32, ptr %p, i64 %iv | |
| %v = load i32, ptr %ptr | |
| %add = add i32 %v, 1 | |
| store i32 %add, ptr %ptr | |
| %iv.next = add i64 %iv, 1 | |
| %cmp.loop = icmp eq i64 %iv.next, %n | |
| br i1 %cmp.loop, label %exit, label %loop, !prof !6, !llvm.loop !3 | |
| exit: | |
| ret void | |
| } | |
| !0 = !{!"function_entry_count", i64 1000} | |
| !1 = !{!"branch_weights", i32 1, i32 1023} | |
| !2 = distinct !{!2, !4} | |
| !3 = distinct !{!3, !5} | |
| !4 = !{!"llvm.loop.estimated_trip_count", i32 0} | |
| !5 = !{!"llvm.loop.estimated_trip_count", i32 1024} | |
| !6 = !{!"branch_weights", i32 1023, i32 1} | |
| ;. | |
| ; CHECK: [[PROF0]] = !{!"function_entry_count", i64 1000} | |
| ; CHECK: [[PROF1]] = !{!"branch_weights", i32 1, i32 1023} | |
| ; CHECK: [[LOOP2]] = distinct !{[[LOOP2]], [[META3:![0-9]+]]} | |
| ; CHECK: [[META3]] = !{!"llvm.loop.estimated_trip_count", i32 0} | |
| ; CHECK: [[PROF4]] = !{!"branch_weights", i32 14637126, i32 2132846522} | |
| ; CHECK: [[PROF5]] = !{!"branch_weights", i32 16719984, i32 2130763664} | |
| ; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[META7:![0-9]+]]} | |
| ; CHECK: [[META7]] = !{!"llvm.loop.estimated_trip_count", i32 128} | |
| ; CHECK: [[PROF8]] = !{!"branch_weights", i32 1878129346, i32 269354302} | |
| ; CHECK: [[PROF9]] = !{!"branch_weights", i32 1610087680, i32 537395968} | |
| ; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[META3]], [[META11:![0-9]+]]} | |
| ; CHECK: [[META11]] = !{!"llvm.loop.unroll.disable"} | |
| ; CHECK: [[PROF12]] = !{!"branch_weights", i32 -2147483648, i32 0} | |
| ; CHECK: [[LOOP13]] = distinct !{[[LOOP13]], [[META7]]} | |
| ; CHECK: [[PROF14]] = !{!"branch_weights", i32 2097152, i32 2145386496} | |
| ; CHECK: [[LOOP15]] = distinct !{[[LOOP15]], [[META3]], [[META11]]} | |
| ;. | |
| ; FORCED: [[PROF0]] = !{!"function_entry_count", i64 1000} | |
| ; FORCED: [[PROF1]] = !{!"branch_weights", i32 6285314, i32 2141198334} | |
| ; FORCED: [[PROF2]] = !{!"branch_weights", i32 8376328, i32 2139107320} | |
| ; FORCED: [[LOOP3]] = distinct !{[[LOOP3]], [[META4:![0-9]+]], [[META5:![0-9]+]]} | |
| ; FORCED: [[META4]] = !{!"llvm.loop.estimated_trip_count", i32 0} | |
| ; FORCED: [[META5]] = !{!"llvm.loop.unroll.disable"} | |
| ; FORCED: [[PROF6]] = !{!"branch_weights", i32 1609825664, i32 537657984} | |
| ; FORCED: [[PROF7]] = !{!"branch_weights", i32 1073392014, i32 1074091634} | |
| ; FORCED: [[LOOP8]] = distinct !{[[LOOP8]], [[META4]], [[META5]]} | |
| ; FORCED: [[LOOP9]] = distinct !{[[LOOP9]], [[META10:![0-9]+]], [[META5]]} | |
| ; FORCED: [[META10]] = !{!"llvm.loop.estimated_trip_count", i32 256} | |
| ; FORCED: [[LOOP11]] = distinct !{[[LOOP11]], [[META4]], [[META5]]} | |
| ; FORCED: [[PROF12]] = !{!"branch_weights", i32 2147483646, i32 2} | |
| ; FORCED: [[PROF13]] = !{!"branch_weights", i32 -2147483648, i32 0} | |
| ; FORCED: [[LOOP14]] = distinct !{[[LOOP14]], [[META10]], [[META5]]} | |
| ; FORCED: [[PROF15]] = !{!"branch_weights", i32 2097152, i32 2145386496} | |
| ; FORCED: [[PROF16]] = !{!"branch_weights", i32 2097146, i32 2145386502} | |
| ; FORCED: [[LOOP17]] = distinct !{[[LOOP17]], [[META4]], [[META5]]} | |
| ;. |