| ; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter-out-after "middle.block" --version 6 |
| ; RUN: opt -passes=loop-vectorize -force-vector-width=4 -force-vector-interleave=1 \ |
| ; RUN: -tail-folding-policy=must-fold-tail -force-tail-folding-style=data \ |
| ; RUN: -force-target-supports-masked-memory-ops -disable-output \ |
| ; RUN: -vplan-print-after="printFinalVPlan$" %s 2>&1 | FileCheck %s |
| ; REQUIRES: asserts |
| |
| ; Under tail folding, two identical masked loads from the same address are CSE'd. |
| define void @cse_duplicate_masked_load(ptr noalias %a, ptr noalias %b, i64 %n) { |
| ; CHECK-LABEL: VPlan for loop in 'cse_duplicate_masked_load' |
| ; CHECK: VPlan 'Final VPlan for VF={4},UF={1}' { |
| ; CHECK-NEXT: Live-in ir<%n> = original trip-count |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: ir-bb<entry>: |
| ; CHECK-NEXT: Successor(s): vector.ph |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: vector.ph: |
| ; CHECK-NEXT: EMIT vp<%n.rnd.up> = add ir<%n>, ir<3> |
| ; CHECK-NEXT: EMIT vp<[[VP2:%[0-9]+]]> = and vp<%n.rnd.up>, ir<3> |
| ; CHECK-NEXT: EMIT vp<%n.vec> = sub vp<%n.rnd.up>, vp<[[VP2]]> |
| ; CHECK-NEXT: Successor(s): vector.body |
| ; CHECK-EMPTY: |
| ; CHECK-NEXT: vector.body: |
| ; CHECK-NEXT: EMIT-SCALAR vp<%index> = phi [ ir<0>, vector.ph ], [ vp<%index.next>, vector.body ] |
| ; CHECK-NEXT: EMIT vp<%active.lane.mask> = active lane mask vp<%index>, ir<%n> |
| ; CHECK-NEXT: CLONE ir<%gep.a> = getelementptr inbounds ir<%a>, vp<%index> |
| ; CHECK-NEXT: WIDEN ir<%x> = load ir<%gep.a>, vp<%active.lane.mask> |
| ; CHECK-NEXT: WIDEN ir<%sum> = add ir<%x>, ir<%x> |
| ; CHECK-NEXT: CLONE ir<%gep.b> = getelementptr inbounds ir<%b>, vp<%index> |
| ; CHECK-NEXT: WIDEN store ir<%gep.b>, ir<%sum>, vp<%active.lane.mask> |
| ; CHECK-NEXT: EMIT vp<%index.next> = add vp<%index>, ir<4> |
| ; CHECK-NEXT: EMIT vp<[[VP3:%[0-9]+]]> = icmp eq vp<%index.next>, vp<%n.vec> |
| ; CHECK-NEXT: EMIT branch-on-cond vp<[[VP3]]> |
| ; CHECK-NEXT: Successor(s): middle.block, vector.body |
| ; |
| entry: |
| br label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| %gep.a = getelementptr inbounds i32, ptr %a, i64 %iv |
| %x = load i32, ptr %gep.a, align 4 |
| %y = load i32, ptr %gep.a, align 4 |
| %sum = add i32 %x, %y |
| %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv |
| store i32 %sum, ptr %gep.b, align 4 |
| %iv.next = add i64 %iv, 1 |
| %ec = icmp eq i64 %iv.next, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |