| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --filter "br i1|= select |!prof|!llvm.loop|^.*:" --version 6 |
| ; RUN: opt -passes=loop-vectorize -force-vector-width=4 -force-vector-interleave=1 -S %s | FileCheck %s |
| |
| ; Tail folding masks the body on the header mask, so the guard's frequency is |
| ; unknown. |
| define void @tail_folded_predicated_store(ptr noalias %a, ptr noalias %b, i64 %n) optsize !prof !0 { |
| ; CHECK-LABEL: define void @tail_folded_predicated_store( |
| ; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], i64 [[N:%.*]]) #[[ATTR0:[0-9]+]] !prof [[PROF0:![0-9]+]] { |
| ; CHECK: [[ENTRY:.*:]] |
| ; CHECK: [[VECTOR_PH:.*:]] |
| ; CHECK: [[VECTOR_BODY:.*]]: |
| ; CHECK: br i1 [[TMP5:%.*]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]] |
| ; CHECK: [[PRED_LOAD_IF]]: |
| ; CHECK: [[PRED_LOAD_CONTINUE]]: |
| ; CHECK: br i1 [[TMP10:%.*]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2:.*]] |
| ; CHECK: [[PRED_LOAD_IF1]]: |
| ; CHECK: [[PRED_LOAD_CONTINUE2]]: |
| ; CHECK: br i1 [[TMP15:%.*]], label %[[PRED_LOAD_IF3:.*]], label %[[PRED_LOAD_CONTINUE4:.*]] |
| ; CHECK: [[PRED_LOAD_IF3]]: |
| ; CHECK: [[PRED_LOAD_CONTINUE4]]: |
| ; CHECK: br i1 [[TMP20:%.*]], label %[[PRED_LOAD_IF5:.*]], label %[[PRED_LOAD_CONTINUE6:.*]] |
| ; CHECK: [[PRED_LOAD_IF5]]: |
| ; CHECK: [[PRED_LOAD_CONTINUE6]]: |
| ; CHECK: [[TMP26:%.*]] = select <4 x i1> [[TMP1:%.*]], <4 x i1> [[TMP25:%.*]], <4 x i1> zeroinitializer |
| ; CHECK: br i1 [[TMP27:%.*]], label %[[PRED_STORE_IF:.*]], label %[[PRED_STORE_CONTINUE:.*]], !prof [[PROF1:![0-9]+]] |
| ; CHECK: [[PRED_STORE_IF]]: |
| ; CHECK: [[PRED_STORE_CONTINUE]]: |
| ; CHECK: br i1 [[TMP30:%.*]], label %[[PRED_STORE_IF7:.*]], label %[[PRED_STORE_CONTINUE8:.*]], !prof [[PROF1]] |
| ; CHECK: [[PRED_STORE_IF7]]: |
| ; CHECK: [[PRED_STORE_CONTINUE8]]: |
| ; CHECK: br i1 [[TMP33:%.*]], label %[[PRED_STORE_IF9:.*]], label %[[PRED_STORE_CONTINUE10:.*]], !prof [[PROF1]] |
| ; CHECK: [[PRED_STORE_IF9]]: |
| ; CHECK: [[PRED_STORE_CONTINUE10]]: |
| ; CHECK: br i1 [[TMP36:%.*]], label %[[PRED_STORE_IF11:.*]], label %[[PRED_STORE_CONTINUE12:.*]], !prof [[PROF1]] |
| ; CHECK: [[PRED_STORE_IF11]]: |
| ; CHECK: [[PRED_STORE_CONTINUE12]]: |
| ; CHECK: br i1 [[TMP39:%.*]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !prof [[PROF2:![0-9]+]], !llvm.loop [[LOOP3:![0-9]+]] |
| ; CHECK: [[MIDDLE_BLOCK]]: |
| ; CHECK: [[EXIT:.*:]] |
| ; |
| entry: |
| br label %loop.header |
| |
| loop.header: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] |
| %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv |
| %l = load i32, ptr %gep.b, align 4 |
| %c = icmp sgt i32 %l, 0 |
| br i1 %c, label %then, label %loop.latch, !prof !1 |
| |
| then: |
| %gep.a = getelementptr inbounds i32, ptr %a, i64 %iv |
| store i32 %l, ptr %gep.a, align 4 |
| br label %loop.latch |
| |
| loop.latch: |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop.header, !prof !2 |
| |
| exit: |
| ret void |
| } |
| |
| ; Same without tail folding, where the guard keeps the original weights. |
| define void @predicated_store(ptr noalias %a, ptr noalias %b, i64 %n) !prof !0 { |
| ; CHECK-LABEL: define void @predicated_store( |
| ; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], i64 [[N:%.*]]) !prof [[PROF0]] { |
| ; CHECK: [[ENTRY:.*:]] |
| ; CHECK: br i1 [[MIN_ITERS_CHECK:%.*]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]], !prof [[PROF7:![0-9]+]] |
| ; CHECK: [[VECTOR_PH]]: |
| ; CHECK: [[VECTOR_BODY:.*]]: |
| ; CHECK: br i1 [[TMP3:%.*]], label %[[PRED_STORE_IF:.*]], label %[[PRED_STORE_CONTINUE:.*]], !prof [[PROF1]] |
| ; CHECK: [[PRED_STORE_IF]]: |
| ; CHECK: [[PRED_STORE_CONTINUE]]: |
| ; CHECK: br i1 [[TMP6:%.*]], label %[[PRED_STORE_IF1:.*]], label %[[PRED_STORE_CONTINUE2:.*]], !prof [[PROF1]] |
| ; CHECK: [[PRED_STORE_IF1]]: |
| ; CHECK: [[PRED_STORE_CONTINUE2]]: |
| ; CHECK: br i1 [[TMP10:%.*]], label %[[PRED_STORE_IF3:.*]], label %[[PRED_STORE_CONTINUE4:.*]], !prof [[PROF1]] |
| ; CHECK: [[PRED_STORE_IF3]]: |
| ; CHECK: [[PRED_STORE_CONTINUE4]]: |
| ; CHECK: br i1 [[TMP14:%.*]], label %[[PRED_STORE_IF5:.*]], label %[[PRED_STORE_CONTINUE6:.*]], !prof [[PROF1]] |
| ; CHECK: [[PRED_STORE_IF5]]: |
| ; CHECK: [[PRED_STORE_CONTINUE6]]: |
| ; CHECK: br i1 [[TMP18:%.*]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !prof [[PROF2]], !llvm.loop [[LOOP8:![0-9]+]] |
| ; CHECK: [[MIDDLE_BLOCK]]: |
| ; CHECK: br i1 [[CMP_N:%.*]], label %[[EXIT:.*]], label %[[SCALAR_PH]], !prof [[PROF1]] |
| ; CHECK: [[SCALAR_PH]]: |
| ; CHECK: [[LOOP_HEADER:.*]]: |
| ; CHECK: br i1 [[C:%.*]], label %[[THEN:.*]], label %[[LOOP_LATCH:.*]], !prof [[PROF1]] |
| ; CHECK: [[THEN]]: |
| ; CHECK: [[LOOP_LATCH]]: |
| ; CHECK: br i1 [[EC:%.*]], label %[[EXIT]], label %[[LOOP_HEADER]], !prof [[PROF9:![0-9]+]], !llvm.loop [[LOOP10:![0-9]+]] |
| ; CHECK: [[EXIT]]: |
| ; |
| entry: |
| br label %loop.header |
| |
| loop.header: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] |
| %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv |
| %l = load i32, ptr %gep.b, align 4 |
| %c = icmp sgt i32 %l, 0 |
| br i1 %c, label %then, label %loop.latch, !prof !1 |
| |
| then: |
| %gep.a = getelementptr inbounds i32, ptr %a, i64 %iv |
| store i32 %l, ptr %gep.a, align 4 |
| br label %loop.latch |
| |
| loop.latch: |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop.header, !prof !2 |
| |
| exit: |
| ret void |
| } |
| |
| define void @tail_folded_predicated_store_not_profiled(ptr noalias %a, ptr noalias %b, i64 %n) optsize { |
| ; CHECK-LABEL: define void @tail_folded_predicated_store_not_profiled( |
| ; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], i64 [[N:%.*]]) #[[ATTR0]] { |
| ; CHECK: [[ENTRY:.*:]] |
| ; CHECK: [[VECTOR_PH:.*:]] |
| ; CHECK: [[VECTOR_BODY:.*]]: |
| ; CHECK: br i1 [[TMP5:%.*]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]] |
| ; CHECK: [[PRED_LOAD_IF]]: |
| ; CHECK: [[PRED_LOAD_CONTINUE]]: |
| ; CHECK: br i1 [[TMP10:%.*]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2:.*]] |
| ; CHECK: [[PRED_LOAD_IF1]]: |
| ; CHECK: [[PRED_LOAD_CONTINUE2]]: |
| ; CHECK: br i1 [[TMP15:%.*]], label %[[PRED_LOAD_IF3:.*]], label %[[PRED_LOAD_CONTINUE4:.*]] |
| ; CHECK: [[PRED_LOAD_IF3]]: |
| ; CHECK: [[PRED_LOAD_CONTINUE4]]: |
| ; CHECK: br i1 [[TMP20:%.*]], label %[[PRED_LOAD_IF5:.*]], label %[[PRED_LOAD_CONTINUE6:.*]] |
| ; CHECK: [[PRED_LOAD_IF5]]: |
| ; CHECK: [[PRED_LOAD_CONTINUE6]]: |
| ; CHECK: [[TMP26:%.*]] = select <4 x i1> [[TMP1:%.*]], <4 x i1> [[TMP25:%.*]], <4 x i1> zeroinitializer |
| ; CHECK: br i1 [[TMP27:%.*]], label %[[PRED_STORE_IF:.*]], label %[[PRED_STORE_CONTINUE:.*]], !prof [[PROF1]] |
| ; CHECK: [[PRED_STORE_IF]]: |
| ; CHECK: [[PRED_STORE_CONTINUE]]: |
| ; CHECK: br i1 [[TMP30:%.*]], label %[[PRED_STORE_IF7:.*]], label %[[PRED_STORE_CONTINUE8:.*]], !prof [[PROF1]] |
| ; CHECK: [[PRED_STORE_IF7]]: |
| ; CHECK: [[PRED_STORE_CONTINUE8]]: |
| ; CHECK: br i1 [[TMP33:%.*]], label %[[PRED_STORE_IF9:.*]], label %[[PRED_STORE_CONTINUE10:.*]], !prof [[PROF1]] |
| ; CHECK: [[PRED_STORE_IF9]]: |
| ; CHECK: [[PRED_STORE_CONTINUE10]]: |
| ; CHECK: br i1 [[TMP36:%.*]], label %[[PRED_STORE_IF11:.*]], label %[[PRED_STORE_CONTINUE12:.*]], !prof [[PROF1]] |
| ; CHECK: [[PRED_STORE_IF11]]: |
| ; CHECK: [[PRED_STORE_CONTINUE12]]: |
| ; CHECK: br i1 [[TMP39:%.*]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !prof [[PROF2]], !llvm.loop [[LOOP12:![0-9]+]] |
| ; CHECK: [[MIDDLE_BLOCK]]: |
| ; CHECK: [[EXIT:.*:]] |
| ; |
| entry: |
| br label %loop.header |
| |
| loop.header: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] |
| %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv |
| %l = load i32, ptr %gep.b, align 4 |
| %c = icmp sgt i32 %l, 0 |
| br i1 %c, label %then, label %loop.latch, !prof !1 |
| |
| then: |
| %gep.a = getelementptr inbounds i32, ptr %a, i64 %iv |
| store i32 %l, ptr %gep.a, align 4 |
| br label %loop.latch |
| |
| loop.latch: |
| %iv.next = add nuw nsw i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop.header, !prof !2 |
| |
| exit: |
| ret void |
| } |
| |
| !0 = !{!"function_entry_count", i64 1000} |
| !1 = !{!"branch_weights", i32 1, i32 3} |
| !2 = !{!"branch_weights", i32 1, i32 99} |
| ;. |
| ; CHECK: [[PROF0]] = !{!"function_entry_count", i64 1000} |
| ; CHECK: [[PROF1]] = !{!"branch_weights", i32 1, i32 3} |
| ; CHECK: [[PROF2]] = !{!"branch_weights", i32 1, i32 24} |
| ; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META4:![0-9]+]], [[META5:![0-9]+]], [[META6:![0-9]+]]} |
| ; CHECK: [[META4]] = !{!"llvm.loop.isvectorized", i32 1} |
| ; CHECK: [[META5]] = !{!"llvm.loop.unroll.runtime.disable"} |
| ; CHECK: [[META6]] = !{!"llvm.loop.estimated_trip_count", i32 25} |
| ; CHECK: [[PROF7]] = !{!"branch_weights", i32 1, i32 127} |
| ; CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[META4]], [[META5]], [[META6]]} |
| ; CHECK: [[PROF9]] = !{!"branch_weights", i32 1, i32 0} |
| ; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[META5]], [[META4]], [[META11:![0-9]+]]} |
| ; CHECK: [[META11]] = !{!"llvm.loop.estimated_trip_count", i32 0} |
| ; CHECK: [[LOOP12]] = distinct !{[[LOOP12]], [[META4]], [[META5]], [[META6]]} |
| ;. |