blob: ac97db6b4947adad043b3f1779e73ffea74a16c0 [file] [edit]
; 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
}