| ; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "Cost of.*REPLICATE" --version 6 |
| ; REQUIRES: asserts |
| ; RUN: opt -passes=loop-vectorize -force-vector-width=2 -force-vector-interleave=1 -disable-output -debug-only=loop-vectorize %s 2>&1 | FileCheck %s |
| |
| ; The predicate is taken 1 in 4 iterations (reciprocal 4): cost 10 / 4 -> 2.5. |
| define void @predicated_udiv_p25(ptr %a, i32 %n) { |
| ; CHECK-LABEL: 'predicated_udiv_p25' |
| ; CHECK: Cost of 0 for VF 2: REPLICATE ir<%gep>.1 = getelementptr inbounds ir<%a>, vp<[[VP6:%[0-9]+]]> |
| ; CHECK: Cost of 2.5 for VF 2: REPLICATE ir<%d> = udiv ir<%val>, ir<7> |
| ; CHECK: Cost of 0 for VF 2: REPLICATE store ir<%d>, ir<%gep>.1 |
| ; CHECK: Cost of 0 for VF 2: REPLICATE ir<%gep>.1 = getelementptr inbounds ir<%a>, vp<[[VP6]]> |
| ; CHECK: Cost of 2.5 for VF 2: REPLICATE ir<%d> = udiv ir<%val>, ir<7> |
| ; CHECK: Cost of 0 for VF 2: REPLICATE store ir<%d>, ir<%gep>.1 |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i32 [ 0, %entry ], [ %iv.next, %latch ] |
| %gep = getelementptr inbounds i32, ptr %a, i32 %iv |
| %val = load i32, ptr %gep, align 4 |
| %cmp = icmp sgt i32 %val, 0 |
| br i1 %cmp, label %if.then, label %latch, !prof !1 |
| |
| if.then: |
| %d = udiv i32 %val, 7 |
| store i32 %d, ptr %gep, align 4 |
| br label %latch |
| |
| latch: |
| %iv.next = add nuw nsw i32 %iv, 1 |
| %exitcond = icmp eq i32 %iv.next, %n |
| br i1 %exitcond, label %exit, label %loop, !prof !0 |
| |
| exit: |
| ret void |
| } |
| |
| ; The predicate is taken 1 in 8 iterations (reciprocal 8): cost 10 / 8 -> 1.25. |
| ; A less likely predicate makes the predicated udiv look cheaper than at 1/4. |
| define void @predicated_udiv_p12(ptr %a, i32 %n) { |
| ; CHECK-LABEL: 'predicated_udiv_p12' |
| ; CHECK: Cost of 0 for VF 2: REPLICATE ir<%gep>.1 = getelementptr inbounds ir<%a>, vp<[[VP6:%[0-9]+]]> |
| ; CHECK: Cost of 1.25 for VF 2: REPLICATE ir<%d> = udiv ir<%val>, ir<7> |
| ; CHECK: Cost of 0 for VF 2: REPLICATE store ir<%d>, ir<%gep>.1 |
| ; CHECK: Cost of 0 for VF 2: REPLICATE ir<%gep>.1 = getelementptr inbounds ir<%a>, vp<[[VP6]]> |
| ; CHECK: Cost of 1.25 for VF 2: REPLICATE ir<%d> = udiv ir<%val>, ir<7> |
| ; CHECK: Cost of 0 for VF 2: REPLICATE store ir<%d>, ir<%gep>.1 |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i32 [ 0, %entry ], [ %iv.next, %latch ] |
| %gep = getelementptr inbounds i32, ptr %a, i32 %iv |
| %val = load i32, ptr %gep, align 4 |
| %cmp = icmp sgt i32 %val, 0 |
| br i1 %cmp, label %if.then, label %latch, !prof !2 |
| |
| if.then: |
| %d = udiv i32 %val, 7 |
| store i32 %d, ptr %gep, align 4 |
| br label %latch |
| |
| latch: |
| %iv.next = add nuw nsw i32 %iv, 1 |
| %exitcond = icmp eq i32 %iv.next, %n |
| br i1 %exitcond, label %exit, label %loop, !prof !0 |
| |
| exit: |
| ret void |
| } |
| |
| ; Without profile data the cost model is still self-contained: the recorded |
| ; reciprocal comes from block frequency info, which defaults to an even 50/50 |
| ; split for the unprofiled predicate (reciprocal 2), so cost 10 / 2 -> 5. |
| define void @predicated_udiv_no_profile(ptr %a, i32 %n) { |
| ; CHECK-LABEL: 'predicated_udiv_no_profile' |
| ; CHECK: Cost of 0 for VF 2: REPLICATE ir<%gep>.1 = getelementptr inbounds ir<%a>, vp<[[VP6:%[0-9]+]]> |
| ; CHECK: Cost of 5 for VF 2: REPLICATE ir<%d> = udiv ir<%val>, ir<7> |
| ; CHECK: Cost of 0 for VF 2: REPLICATE store ir<%d>, ir<%gep>.1 |
| ; CHECK: Cost of 0 for VF 2: REPLICATE ir<%gep>.1 = getelementptr inbounds ir<%a>, vp<[[VP6]]> |
| ; CHECK: Cost of 5 for VF 2: REPLICATE ir<%d> = udiv ir<%val>, ir<7> |
| ; CHECK: Cost of 0 for VF 2: REPLICATE store ir<%d>, ir<%gep>.1 |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i32 [ 0, %entry ], [ %iv.next, %latch ] |
| %gep = getelementptr inbounds i32, ptr %a, i32 %iv |
| %val = load i32, ptr %gep, align 4 |
| %cmp = icmp sgt i32 %val, 0 |
| br i1 %cmp, label %if.then, label %latch |
| |
| if.then: |
| %d = udiv i32 %val, 7 |
| store i32 %d, ptr %gep, align 4 |
| br label %latch |
| |
| latch: |
| %iv.next = add nuw nsw i32 %iv, 1 |
| %exitcond = icmp eq i32 %iv.next, %n |
| br i1 %exitcond, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; Two adjacent predicated blocks guarded by the same condition are merged into a |
| ; single replicate region. 2 branches with same condition have different probabilities. |
| define void @merged_regions_use_conservative_probability(ptr noalias %a, ptr noalias %b, i32 %n, i32 %x, i32 %y) { |
| ; CHECK-LABEL: 'merged_regions_use_conservative_probability' |
| ; CHECK: Cost of 0 for VF 2: REPLICATE ir<%gep>.1 = getelementptr inbounds ir<%a>, vp<[[VP7:%[0-9]+]]> |
| ; CHECK: Cost of 3000000 for VF 2: REPLICATE store vp<[[VP6:%[0-9]+]]>, ir<%gep>.1 |
| ; CHECK: Cost of 0 for VF 2: REPLICATE ir<%d2> = sdiv ir<%val>, ir<%y> |
| ; CHECK: Cost of 0 for VF 2: REPLICATE ir<%gep.b> = getelementptr inbounds ir<%b>, vp<[[VP7]]> |
| ; CHECK: Cost of 3000000 for VF 2: REPLICATE store ir<%d2>, ir<%gep.b> |
| ; CHECK: Cost of 0 for VF 2: REPLICATE ir<%gep>.1 = getelementptr inbounds ir<%a>, vp<[[VP7]]> |
| ; CHECK: Cost of 3000000 for VF 2: REPLICATE store vp<[[VP6]]>, ir<%gep>.1 |
| ; CHECK: Cost of 0 for VF 2: REPLICATE ir<%d2> = sdiv ir<%val>, ir<%y> |
| ; CHECK: Cost of 0 for VF 2: REPLICATE ir<%gep.b> = getelementptr inbounds ir<%b>, vp<[[VP7]]> |
| ; CHECK: Cost of 3000000 for VF 2: REPLICATE store ir<%d2>, ir<%gep.b> |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i32 [ 0, %entry ], [ %iv.next, %latch ] |
| %gep = getelementptr inbounds i32, ptr %a, i32 %iv |
| %val = load i32, ptr %gep, align 4 |
| %cmp = icmp sgt i32 %val, 0 |
| br i1 %cmp, label %then1, label %bb1, !prof !1 |
| |
| then1: |
| %d1 = sdiv i32 %val, %x |
| store i32 %d1, ptr %gep, align 4 |
| br label %bb1 |
| |
| bb1: |
| br i1 %cmp, label %then2, label %latch, !prof !3 |
| |
| then2: |
| %d2 = sdiv i32 %val, %y |
| %gep.b = getelementptr inbounds i32, ptr %b, i32 %iv |
| store i32 %d2, ptr %gep.b, align 4 |
| br label %latch |
| |
| latch: |
| %iv.next = add nuw nsw i32 %iv, 1 |
| %exitcond = icmp eq i32 %iv.next, %n |
| br i1 %exitcond, label %exit, label %loop, !prof !0 |
| |
| exit: |
| ret void |
| } |
| |
| define void @sunk_recipe_uses_region_probability(ptr noalias %a, ptr noalias %b, i32 %n, i32 %x) { |
| ; CHECK-LABEL: 'sunk_recipe_uses_region_probability' |
| ; CHECK: Cost of 2.5 for VF 2: REPLICATE ir<%rem> = srem ir<%val>, ir<%x> |
| ; CHECK: Cost of 0 for VF 2: REPLICATE ir<%gep.b> = getelementptr inbounds ir<%b>, vp<[[VP6:%[0-9]+]]> |
| ; CHECK: Cost of 0 for VF 2: REPLICATE store ir<%rem>, ir<%gep.b> |
| ; CHECK: Cost of 2.5 for VF 2: REPLICATE ir<%rem> = srem ir<%val>, ir<%x> |
| ; CHECK: Cost of 0 for VF 2: REPLICATE ir<%gep.b> = getelementptr inbounds ir<%b>, vp<[[VP6]]> |
| ; CHECK: Cost of 0 for VF 2: REPLICATE store ir<%rem>, ir<%gep.b> |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i32 [ 0, %entry ], [ %iv.next, %latch ] |
| %gep = getelementptr inbounds i32, ptr %a, i32 %iv |
| %val = load i32, ptr %gep, align 4 |
| %cmp = icmp sgt i32 %val, 0 |
| br i1 %cmp, label %if.then, label %latch, !prof !1 |
| |
| if.then: |
| %rem = srem i32 %val, %x |
| %gep.b = getelementptr inbounds i32, ptr %b, i32 %iv |
| store i32 %rem, ptr %gep.b, align 4 |
| br label %latch |
| |
| latch: |
| %iv.next = add nuw nsw i32 %iv, 1 |
| %exitcond = icmp eq i32 %iv.next, %n |
| br i1 %exitcond, label %exit, label %loop, !prof !0 |
| |
| exit: |
| ret void |
| } |
| |
| !0 = !{!"branch_weights", i32 1, i32 1000} |
| !1 = !{!"branch_weights", i32 1, i32 3} |
| !2 = !{!"branch_weights", i32 1, i32 7} |
| !3 = !{!"branch_weights", i32 1, i32 99} |