#201783 wants to optimize blend masks by peeking through the contents of other phi nodes. Currently we eagerly convert phis to blends in reverse post order, so switch it to post order so that phis at the bottom can see the phis in their uses.
753 lines
24 KiB
LLVM
753 lines
24 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6
|
|
; RUN: opt -disable-output < %s -p loop-vectorize -vplan-print-after=introduceMasksAndLinearize -vplan-print-vector-region-scope 2>&1 | FileCheck %s
|
|
|
|
define void @diamond_phi(ptr %a) {
|
|
; CHECK-LABEL: VPlan for loop in 'diamond_phi'
|
|
; CHECK-NEXT: <x1> vector loop: {
|
|
; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = CANONICAL-IV
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: vector.body:
|
|
; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]>
|
|
; CHECK-NEXT: EMIT ir<%gep> = getelementptr ir<%a>, ir<%iv>
|
|
; CHECK-NEXT: EMIT ir<%c0> = icmp sle ir<%iv>, ir<0>
|
|
; CHECK-NEXT: Successor(s): bb2
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb2:
|
|
; CHECK-NEXT: EMIT vp<[[VP4:%[0-9]+]]> = not ir<%c0>
|
|
; CHECK-NEXT: EMIT ir<%add2> = add ir<%iv>, ir<2>, vp<[[VP4]]>
|
|
; CHECK-NEXT: Successor(s): bb1
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb1:
|
|
; CHECK-NEXT: EMIT ir<%add1> = add ir<%iv>, ir<1>, ir<%c0>
|
|
; CHECK-NEXT: Successor(s): bb4
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb4:
|
|
; CHECK-NEXT: BLEND ir<%phi4> = ir<%add2>/vp<[[VP4]]> ir<%add1>/ir<%c0>
|
|
; CHECK-NEXT: EMIT store ir<%phi4>, ir<%gep>
|
|
; CHECK-NEXT: EMIT ir<%iv.next> = add nuw nsw ir<%iv>, ir<1>
|
|
; CHECK-NEXT: EMIT ir<%ec> = icmp eq ir<%iv.next>, ir<128>
|
|
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, vp<[[VP1:%[0-9]+]]>
|
|
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2:%[0-9]+]]>
|
|
; CHECK-NEXT: No successors
|
|
; CHECK-NEXT: }
|
|
; CHECK-NEXT: Successor(s): middle.block
|
|
;
|
|
entry:
|
|
br label %bb0
|
|
|
|
bb0:
|
|
; bb0
|
|
; / \
|
|
; bb1 bb2
|
|
; \ /
|
|
; bb4
|
|
; Verify that bb4 is unmasked.
|
|
%iv = phi i64 [0, %entry], [%iv.next, %bb4]
|
|
%gep = getelementptr i64, ptr %a, i64 %iv
|
|
%c0 = icmp sle i64 %iv, 0
|
|
br i1 %c0, label %bb1, label %bb2
|
|
|
|
bb1:
|
|
%add1 = add i64 %iv, 1
|
|
br label %bb4
|
|
|
|
bb2:
|
|
%add2 = add i64 %iv, 2
|
|
br label %bb4
|
|
|
|
bb4:
|
|
%phi4 = phi i64 [%add1, %bb1], [%add2, %bb2]
|
|
store i64 %phi4, ptr %gep
|
|
%iv.next = add nsw nuw i64 %iv, 1
|
|
%ec = icmp eq i64 %iv.next, 128
|
|
br i1 %ec, label %exit, label %bb0
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @mask_reuse(ptr %a) {
|
|
; CHECK-LABEL: VPlan for loop in 'mask_reuse'
|
|
; CHECK-NEXT: <x1> vector loop: {
|
|
; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = CANONICAL-IV
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: vector.body:
|
|
; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]>
|
|
; CHECK-NEXT: EMIT ir<%gep> = getelementptr ir<%a>, ir<%iv>
|
|
; CHECK-NEXT: EMIT ir<%c0> = icmp sle ir<%iv>, ir<0>
|
|
; CHECK-NEXT: Successor(s): bb1
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb1:
|
|
; CHECK-NEXT: EMIT ir<%add1> = add ir<%iv>, ir<1>, ir<%c0>
|
|
; CHECK-NEXT: EMIT ir<%c1> = icmp sle ir<%iv>, ir<1>, ir<%c0>
|
|
; CHECK-NEXT: Successor(s): bb2
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb2:
|
|
; CHECK-NEXT: EMIT vp<[[VP4:%[0-9]+]]> = logical-and ir<%c0>, ir<%c1>
|
|
; CHECK-NEXT: EMIT ir<%add2> = add ir<%iv>, ir<2>, vp<[[VP4]]>
|
|
; CHECK-NEXT: Successor(s): bb3
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb3:
|
|
; CHECK-NEXT: EMIT vp<[[VP5:%[0-9]+]]> = not ir<%c1>
|
|
; CHECK-NEXT: EMIT vp<[[VP6:%[0-9]+]]> = logical-and ir<%c0>, vp<[[VP5]]>
|
|
; CHECK-NEXT: BLEND ir<%phi3> = ir<%add2>/vp<[[VP4]]> ir<%add1>/vp<[[VP6]]>
|
|
; CHECK-NEXT: EMIT ir<%add3> = add ir<%phi3>, ir<3>, ir<%c0>
|
|
; CHECK-NEXT: Successor(s): bb4
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb4:
|
|
; CHECK-NEXT: EMIT vp<[[VP7:%[0-9]+]]> = not ir<%c0>
|
|
; CHECK-NEXT: BLEND ir<%phi4> = ir<%add3>/ir<%c0> ir<%iv>/vp<[[VP7]]>
|
|
; CHECK-NEXT: EMIT store ir<%phi4>, ir<%gep>
|
|
; CHECK-NEXT: EMIT ir<%iv.next> = add nuw nsw ir<%iv>, ir<1>
|
|
; CHECK-NEXT: EMIT ir<%ec> = icmp eq ir<%iv.next>, ir<128>
|
|
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, vp<[[VP1:%[0-9]+]]>
|
|
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2:%[0-9]+]]>
|
|
; CHECK-NEXT: No successors
|
|
; CHECK-NEXT: }
|
|
; CHECK-NEXT: Successor(s): middle.block
|
|
;
|
|
entry:
|
|
br label %bb0
|
|
|
|
bb0:
|
|
; bb0:
|
|
; / \
|
|
; bb1 \
|
|
; /\ \
|
|
; bb2 | |
|
|
; \ | |
|
|
; bb3 /
|
|
; \ /
|
|
; bb4
|
|
; Verify that bb3 reuse bb1's mask and bb4 is unmasked.
|
|
%iv = phi i64 [0, %entry], [%iv.next, %bb4]
|
|
%gep = getelementptr i64, ptr %a, i64 %iv
|
|
%c0 = icmp sle i64 %iv, 0
|
|
%add0 = add i64 %iv, 0
|
|
br i1 %c0, label %bb1, label %bb4
|
|
|
|
bb1:
|
|
%add1 = add i64 %iv, 1
|
|
%c1 = icmp sle i64 %iv, 1
|
|
br i1 %c1, label %bb2, label %bb3
|
|
|
|
bb2:
|
|
%add2 = add i64 %iv, 2
|
|
br label %bb3
|
|
|
|
bb3:
|
|
%phi3 = phi i64 [%add1, %bb1], [%add2, %bb2]
|
|
%add3 = add i64 %phi3, 3
|
|
br label %bb4
|
|
|
|
bb4:
|
|
%phi4 = phi i64 [%add3, %bb3], [%add0, %bb0]
|
|
store i64 %phi4, ptr %gep
|
|
%iv.next = add nsw nuw i64 %iv, 1
|
|
%ec = icmp eq i64 %iv.next, 128
|
|
br i1 %ec, label %exit, label %bb0
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @optimized_mask(ptr %a) {
|
|
; CHECK-LABEL: VPlan for loop in 'optimized_mask'
|
|
; CHECK-NEXT: <x1> vector loop: {
|
|
; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = CANONICAL-IV
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: vector.body:
|
|
; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]>
|
|
; CHECK-NEXT: EMIT ir<%gep> = getelementptr ir<%a>, ir<%iv>
|
|
; CHECK-NEXT: EMIT ir<%c0> = icmp sle ir<%iv>, ir<0>
|
|
; CHECK-NEXT: Successor(s): bb6
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb6:
|
|
; CHECK-NEXT: EMIT vp<[[VP4:%[0-9]+]]> = not ir<%c0>
|
|
; CHECK-NEXT: EMIT ir<%add6> = add ir<%iv>, ir<6>, vp<[[VP4]]>
|
|
; CHECK-NEXT: EMIT ir<%c6> = icmp sle ir<%iv>, ir<6>, vp<[[VP4]]>
|
|
; CHECK-NEXT: Successor(s): bb1
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb1:
|
|
; CHECK-NEXT: EMIT ir<%c1> = icmp sle ir<%iv>, ir<1>, ir<%c0>
|
|
; CHECK-NEXT: Successor(s): bb3
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb3:
|
|
; CHECK-NEXT: EMIT vp<[[VP5:%[0-9]+]]> = not ir<%c1>
|
|
; CHECK-NEXT: EMIT vp<[[VP6:%[0-9]+]]> = logical-and ir<%c0>, vp<[[VP5]]>
|
|
; CHECK-NEXT: EMIT ir<%add3> = add ir<%iv>, ir<3>, vp<[[VP6]]>
|
|
; CHECK-NEXT: EMIT ir<%c3> = icmp sle ir<%iv>, ir<3>, vp<[[VP6]]>
|
|
; CHECK-NEXT: Successor(s): bb2
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb2:
|
|
; CHECK-NEXT: EMIT vp<[[VP7:%[0-9]+]]> = logical-and ir<%c0>, ir<%c1>
|
|
; CHECK-NEXT: EMIT ir<%add2> = add ir<%iv>, ir<2>, vp<[[VP7]]>
|
|
; CHECK-NEXT: Successor(s): bb4
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb4:
|
|
; CHECK-NEXT: EMIT vp<[[VP8:%[0-9]+]]> = logical-and vp<[[VP6]]>, ir<%c3>
|
|
; CHECK-NEXT: EMIT vp<[[VP9:%[0-9]+]]> = or vp<[[VP8]]>, vp<[[VP7]]>
|
|
; CHECK-NEXT: BLEND ir<%phi4> = ir<%add3>/vp<[[VP8]]> ir<%add2>/vp<[[VP7]]>
|
|
; CHECK-NEXT: EMIT ir<%add4> = add ir<%phi4>, ir<4>, vp<[[VP9]]>
|
|
; CHECK-NEXT: Successor(s): bb5
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb5:
|
|
; CHECK-NEXT: EMIT vp<[[VP10:%[0-9]+]]> = logical-and vp<[[VP4]]>, ir<%c6>
|
|
; CHECK-NEXT: EMIT vp<[[VP11:%[0-9]+]]> = or vp<[[VP10]]>, vp<[[VP9]]>
|
|
; CHECK-NEXT: EMIT vp<[[VP12:%[0-9]+]]> = not ir<%c3>
|
|
; CHECK-NEXT: EMIT vp<[[VP13:%[0-9]+]]> = logical-and vp<[[VP6]]>, vp<[[VP12]]>
|
|
; CHECK-NEXT: EMIT vp<[[VP14:%[0-9]+]]> = or vp<[[VP11]]>, vp<[[VP13]]>
|
|
; CHECK-NEXT: BLEND ir<%phi5> = ir<%add6>/vp<[[VP10]]> ir<%add4>/vp<[[VP9]]> ir<%add3>/vp<[[VP13]]>
|
|
; CHECK-NEXT: EMIT ir<%add5> = add ir<%phi5>, ir<5>, vp<[[VP14]]>
|
|
; CHECK-NEXT: Successor(s): bb7
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb7:
|
|
; CHECK-NEXT: EMIT vp<[[VP15:%[0-9]+]]> = not ir<%c6>
|
|
; CHECK-NEXT: EMIT vp<[[VP16:%[0-9]+]]> = logical-and vp<[[VP4]]>, vp<[[VP15]]>
|
|
; CHECK-NEXT: BLEND ir<%phi7> = ir<%add6>/vp<[[VP16]]> ir<%add5>/vp<[[VP14]]>
|
|
; CHECK-NEXT: EMIT store ir<%phi7>, ir<%gep>
|
|
; CHECK-NEXT: EMIT ir<%iv.next> = add nuw nsw ir<%iv>, ir<1>
|
|
; CHECK-NEXT: EMIT ir<%ec> = icmp eq ir<%iv.next>, ir<128>
|
|
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, vp<[[VP1:%[0-9]+]]>
|
|
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2:%[0-9]+]]>
|
|
; CHECK-NEXT: No successors
|
|
; CHECK-NEXT: }
|
|
; CHECK-NEXT: Successor(s): middle.block
|
|
;
|
|
entry:
|
|
br label %bb0
|
|
|
|
bb0:
|
|
; bb0:
|
|
; / \
|
|
; / \
|
|
; bb1 bb6
|
|
; / \ / |
|
|
; bb2 bb3 / /
|
|
; \ /| / /
|
|
; bb4| / /
|
|
; \ | / /
|
|
; bb5 /
|
|
; \ /
|
|
; bb7
|
|
; TODO: bb5's mask shouldn't depend on c1/c3.
|
|
%iv = phi i64 [0, %entry], [%iv.next, %bb7]
|
|
%gep = getelementptr i64, ptr %a, i64 %iv
|
|
%c0 = icmp sle i64 %iv, 0
|
|
br i1 %c0, label %bb1, label %bb6
|
|
|
|
bb1:
|
|
%add1 = add i64 %iv, 1
|
|
%c1 = icmp sle i64 %iv, 1
|
|
br i1 %c1, label %bb2, label %bb3
|
|
|
|
bb2:
|
|
%add2 = add i64 %iv, 2
|
|
br label %bb4
|
|
|
|
bb3:
|
|
%add3 = add i64 %iv, 3
|
|
%c3 = icmp sle i64 %iv, 3
|
|
br i1 %c3, label %bb4, label %bb5
|
|
|
|
bb4:
|
|
%phi4 = phi i64 [%add2, %bb2], [%add3, %bb3]
|
|
%add4 = add i64 %phi4, 4
|
|
br label %bb5
|
|
|
|
bb5:
|
|
%phi5 = phi i64 [%add4, %bb4], [%add3, %bb3], [%add6, %bb6]
|
|
%add5 = add i64 %phi5, 5
|
|
br label %bb7
|
|
|
|
bb6:
|
|
%add6 = add i64 %iv, 6
|
|
%c6 = icmp sle i64 %iv, 6
|
|
br i1 %c6, label %bb5, label %bb7
|
|
|
|
bb7:
|
|
%phi7 = phi i64 [%add5, %bb5], [%add6, %bb6]
|
|
store i64 %phi7, ptr %gep
|
|
%iv.next = add nsw nuw i64 %iv, 1
|
|
%ec = icmp eq i64 %iv.next, 128
|
|
br i1 %ec, label %exit, label %bb0
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @switch(ptr %a) {
|
|
; CHECK-LABEL: VPlan for loop in 'switch'
|
|
; CHECK-NEXT: <x1> vector loop: {
|
|
; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = CANONICAL-IV
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: vector.body:
|
|
; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]>
|
|
; CHECK-NEXT: EMIT ir<%gep> = getelementptr ir<%a>, ir<%iv>
|
|
; CHECK-NEXT: EMIT ir<%c0> = icmp sle ir<%iv>, ir<0>
|
|
; CHECK-NEXT: Successor(s): bb2
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb2:
|
|
; CHECK-NEXT: EMIT vp<[[VP4:%[0-9]+]]> = not ir<%c0>
|
|
; CHECK-NEXT: EMIT ir<%add2> = add ir<%iv>, ir<2>, vp<[[VP4]]>
|
|
; CHECK-NEXT: EMIT ir<%c2> = icmp sle ir<%iv>, ir<2>, vp<[[VP4]]>
|
|
; CHECK-NEXT: Successor(s): bb1
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb1:
|
|
; CHECK-NEXT: EMIT ir<%add1> = add ir<%iv>, ir<1>, ir<%c0>
|
|
; CHECK-NEXT: Successor(s): bb3
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb3:
|
|
; CHECK-NEXT: EMIT vp<[[VP5:%[0-9]+]]> = logical-and vp<[[VP4]]>, ir<%c2>
|
|
; CHECK-NEXT: EMIT vp<[[VP6:%[0-9]+]]> = icmp eq ir<%iv>, ir<1>
|
|
; CHECK-NEXT: EMIT vp<[[VP7:%[0-9]+]]> = icmp eq ir<%iv>, ir<2>
|
|
; CHECK-NEXT: EMIT vp<[[VP8:%[0-9]+]]> = icmp eq ir<%iv>, ir<3>
|
|
; CHECK-NEXT: EMIT vp<[[VP9:%[0-9]+]]> = logical-and ir<%c0>, vp<[[VP6]]>
|
|
; CHECK-NEXT: EMIT vp<[[VP10:%[0-9]+]]> = or vp<[[VP7]]>, vp<[[VP8]]>
|
|
; CHECK-NEXT: EMIT vp<[[VP11:%[0-9]+]]> = logical-and ir<%c0>, vp<[[VP10]]>
|
|
; CHECK-NEXT: EMIT vp<[[VP12:%[0-9]+]]> = or vp<[[VP9]]>, vp<[[VP11]]>
|
|
; CHECK-NEXT: EMIT vp<[[VP13:%[0-9]+]]> = not vp<[[VP12]]>
|
|
; CHECK-NEXT: EMIT vp<[[VP14:%[0-9]+]]> = logical-and ir<%c0>, vp<[[VP13]]>
|
|
; CHECK-NEXT: EMIT vp<[[VP15:%[0-9]+]]> = or vp<[[VP5]]>, vp<[[VP11]]>
|
|
; CHECK-NEXT: BLEND ir<%phi3> = ir<%add2>/vp<[[VP5]]> ir<%add1>/vp<[[VP11]]> ir<%add1>/vp<[[VP11]]>
|
|
; CHECK-NEXT: EMIT ir<%add3> = add ir<%phi3>, ir<3>, vp<[[VP15]]>
|
|
; CHECK-NEXT: Successor(s): bb4
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb4:
|
|
; CHECK-NEXT: EMIT ir<%add4> = add ir<%iv>, ir<4>, vp<[[VP9]]>
|
|
; CHECK-NEXT: Successor(s): bb5
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb5:
|
|
; CHECK-NEXT: EMIT vp<[[VP16:%[0-9]+]]> = not ir<%c2>
|
|
; CHECK-NEXT: EMIT vp<[[VP17:%[0-9]+]]> = logical-and vp<[[VP4]]>, vp<[[VP16]]>
|
|
; CHECK-NEXT: BLEND ir<%phi5> = ir<%add4>/vp<[[VP9]]> ir<%add3>/vp<[[VP15]]> ir<%add2>/vp<[[VP17]]> ir<%add1>/vp<[[VP14]]>
|
|
; CHECK-NEXT: EMIT store ir<%phi5>, ir<%gep>
|
|
; CHECK-NEXT: EMIT ir<%iv.next> = add nuw nsw ir<%iv>, ir<1>
|
|
; CHECK-NEXT: EMIT ir<%ec> = icmp eq ir<%iv.next>, ir<128>
|
|
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, vp<[[VP1:%[0-9]+]]>
|
|
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2:%[0-9]+]]>
|
|
; CHECK-NEXT: No successors
|
|
; CHECK-NEXT: }
|
|
; CHECK-NEXT: Successor(s): middle.block
|
|
;
|
|
entry:
|
|
br label %bb0
|
|
|
|
bb0:
|
|
; bb0:
|
|
; / \
|
|
; bb1-+ bb2
|
|
; / | \| /\
|
|
; \bb4 bb3|
|
|
; \ \ | /
|
|
; +>bb5
|
|
; Test for blends at switch destinations, including multiple edges from switch
|
|
; to a single block (bb3).
|
|
%iv = phi i64 [0, %entry], [%iv.next, %bb5]
|
|
%gep = getelementptr i64, ptr %a, i64 %iv
|
|
%c0 = icmp sle i64 %iv, 0
|
|
%add0 = add i64 %iv, 0
|
|
br i1 %c0, label %bb1, label %bb2
|
|
|
|
bb1:
|
|
%add1 = add i64 %iv, 1
|
|
switch i64 %iv, label %bb5 [
|
|
i64 1, label %bb4
|
|
i64 2, label %bb3
|
|
i64 3, label %bb3
|
|
]
|
|
|
|
bb2:
|
|
%add2 = add i64 %iv, 2
|
|
%c2 = icmp sle i64 %iv, 2
|
|
br i1 %c2, label %bb3, label %bb5
|
|
|
|
bb3:
|
|
%phi3 = phi i64 [%add1, %bb1], [%add1, %bb1], [%add2, %bb2]
|
|
%add3 = add i64 %phi3, 3
|
|
br label %bb5
|
|
|
|
bb4:
|
|
%add4 = add i64 %iv, 4
|
|
br label %bb5
|
|
|
|
bb5:
|
|
%phi5 = phi i64 [%add1, %bb1], [%add2, %bb2], [%add3, %bb3], [%add4, %bb4]
|
|
store i64 %phi5, ptr %gep
|
|
%iv.next = add nsw nuw i64 %iv, 1
|
|
%ec = icmp eq i64 %iv.next, 128
|
|
br i1 %ec, label %exit, label %bb0
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
; bb0
|
|
; / \
|
|
; bb1 bb2
|
|
; | \ / |
|
|
; | bb4 |
|
|
; \ | /
|
|
; bb5
|
|
;
|
|
; The blend masks for %phi in bb4 should be:
|
|
; bb1 := bb0->bb1 := c0
|
|
; bb2 := bb0->bb2 := !c0
|
|
define void @diamond_phi2(ptr %a, i1 %c1, i1 %c2) {
|
|
; CHECK-LABEL: VPlan for loop in 'diamond_phi2'
|
|
; CHECK-NEXT: <x1> vector loop: {
|
|
; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = CANONICAL-IV
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: vector.body:
|
|
; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]>
|
|
; CHECK-NEXT: EMIT ir<%c0> = icmp sle ir<%iv>, ir<0>
|
|
; CHECK-NEXT: Successor(s): bb2
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb2:
|
|
; CHECK-NEXT: EMIT vp<[[VP4:%[0-9]+]]> = not ir<%c0>
|
|
; CHECK-NEXT: EMIT ir<%add2> = add ir<%iv>, ir<2>, vp<[[VP4]]>
|
|
; CHECK-NEXT: Successor(s): bb1
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb1:
|
|
; CHECK-NEXT: EMIT ir<%add1> = add ir<%iv>, ir<1>, ir<%c0>
|
|
; CHECK-NEXT: Successor(s): bb4
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb4:
|
|
; CHECK-NEXT: EMIT vp<[[VP5:%[0-9]+]]> = logical-and vp<[[VP4]]>, ir<%c2>
|
|
; CHECK-NEXT: EMIT vp<[[VP6:%[0-9]+]]> = logical-and ir<%c0>, ir<%c1>
|
|
; CHECK-NEXT: EMIT vp<[[VP7:%[0-9]+]]> = or vp<[[VP5]]>, vp<[[VP6]]>
|
|
; CHECK-NEXT: BLEND ir<%phi> = ir<%add2>/vp<[[VP5]]> ir<%add1>/vp<[[VP6]]>
|
|
; CHECK-NEXT: EMIT ir<%gep> = getelementptr ir<%a>, ir<%iv>
|
|
; CHECK-NEXT: EMIT store ir<%phi>, ir<%gep>, vp<[[VP7]]>
|
|
; CHECK-NEXT: Successor(s): bb5
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb5:
|
|
; CHECK-NEXT: EMIT ir<%iv.next> = add nuw nsw ir<%iv>, ir<1>
|
|
; CHECK-NEXT: EMIT ir<%ec> = icmp eq ir<%iv.next>, ir<128>
|
|
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, vp<[[VP1:%[0-9]+]]>
|
|
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2:%[0-9]+]]>
|
|
; CHECK-NEXT: No successors
|
|
; CHECK-NEXT: }
|
|
; CHECK-NEXT: Successor(s): middle.block
|
|
;
|
|
entry:
|
|
br label %bb0
|
|
|
|
bb0:
|
|
%iv = phi i64 [0, %entry], [%iv.next, %bb5]
|
|
%c0 = icmp sle i64 %iv, 0
|
|
br i1 %c0, label %bb1, label %bb2
|
|
|
|
bb1:
|
|
%add1 = add i64 %iv, 1
|
|
br i1 %c1, label %bb4, label %bb5
|
|
|
|
bb2:
|
|
%add2 = add i64 %iv, 2
|
|
br i1 %c2, label %bb4, label %bb5
|
|
|
|
bb4:
|
|
%phi = phi i64 [%add1, %bb1], [%add2, %bb2]
|
|
%gep = getelementptr i64, ptr %a, i64 %iv
|
|
store i64 %phi, ptr %gep
|
|
br label %bb5
|
|
|
|
bb5:
|
|
%iv.next = add nsw nuw i64 %iv, 1
|
|
%ec = icmp eq i64 %iv.next, 128
|
|
br i1 %ec, label %exit, label %bb0
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
; bb0
|
|
; / \
|
|
; bb1 bb2
|
|
; / \ |
|
|
; bb3 bb4 |
|
|
; / \ / \ /
|
|
; \ bb5 bb6
|
|
; \ \ / /
|
|
; \ bb7 /
|
|
; \ | /
|
|
; bb8
|
|
;
|
|
; The blend masks for %phi in bb7 should be:
|
|
; bb5 := bb1->bb3 v bb4->bb5 := (c0 && c1) || (c0 && !c1 && c3)
|
|
; bb6 := bb4->bb6 v bb0->bb2 := (c0 && !c1 && !c3) || !c1
|
|
define void @blend_masks(ptr noalias %p, i1 %c0, i1 %c1, i1 %c2, i1 %c3, i1 %c4) {
|
|
; CHECK-LABEL: VPlan for loop in 'blend_masks'
|
|
; CHECK-NEXT: <x1> vector loop: {
|
|
; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = CANONICAL-IV
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: vector.body:
|
|
; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]>
|
|
; CHECK-NEXT: Successor(s): bb2
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb2:
|
|
; CHECK-NEXT: EMIT vp<[[VP4:%[0-9]+]]> = not ir<%c0>
|
|
; CHECK-NEXT: Successor(s): bb1
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb1:
|
|
; CHECK-NEXT: Successor(s): bb4
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb4:
|
|
; CHECK-NEXT: EMIT vp<[[VP5:%[0-9]+]]> = not ir<%c1>
|
|
; CHECK-NEXT: EMIT vp<[[VP6:%[0-9]+]]> = logical-and ir<%c0>, vp<[[VP5]]>
|
|
; CHECK-NEXT: Successor(s): bb6
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb6:
|
|
; CHECK-NEXT: EMIT vp<[[VP7:%[0-9]+]]> = not ir<%c3>
|
|
; CHECK-NEXT: EMIT vp<[[VP8:%[0-9]+]]> = logical-and vp<[[VP6]]>, vp<[[VP7]]>
|
|
; CHECK-NEXT: EMIT vp<[[VP9:%[0-9]+]]> = or vp<[[VP8]]>, vp<[[VP4]]>
|
|
; CHECK-NEXT: Successor(s): bb3
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb3:
|
|
; CHECK-NEXT: EMIT vp<[[VP10:%[0-9]+]]> = logical-and ir<%c0>, ir<%c1>
|
|
; CHECK-NEXT: Successor(s): bb5
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb5:
|
|
; CHECK-NEXT: EMIT vp<[[VP11:%[0-9]+]]> = logical-and vp<[[VP6]]>, ir<%c3>
|
|
; CHECK-NEXT: EMIT vp<[[VP12:%[0-9]+]]> = not ir<%c2>
|
|
; CHECK-NEXT: EMIT vp<[[VP13:%[0-9]+]]> = logical-and vp<[[VP10]]>, vp<[[VP12]]>
|
|
; CHECK-NEXT: EMIT vp<[[VP14:%[0-9]+]]> = or vp<[[VP11]]>, vp<[[VP13]]>
|
|
; CHECK-NEXT: Successor(s): bb7
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb7:
|
|
; CHECK-NEXT: EMIT vp<[[VP15:%[0-9]+]]> = logical-and vp<[[VP9]]>, ir<%c4>
|
|
; CHECK-NEXT: EMIT vp<[[VP16:%[0-9]+]]> = or vp<[[VP15]]>, vp<[[VP14]]>
|
|
; CHECK-NEXT: BLEND ir<%phi> = ir<1>/vp<[[VP15]]> ir<0>/vp<[[VP14]]>
|
|
; CHECK-NEXT: EMIT ir<%gep> = getelementptr ir<%p>, ir<%iv>
|
|
; CHECK-NEXT: EMIT store ir<%phi>, ir<%gep>, vp<[[VP16]]>
|
|
; CHECK-NEXT: Successor(s): bb8
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb8:
|
|
; CHECK-NEXT: EMIT ir<%iv.next> = add ir<%iv>, ir<1>
|
|
; CHECK-NEXT: EMIT ir<%ec> = icmp eq ir<%iv.next>, ir<128>
|
|
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, vp<[[VP1:%[0-9]+]]>
|
|
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2:%[0-9]+]]>
|
|
; CHECK-NEXT: No successors
|
|
; CHECK-NEXT: }
|
|
; CHECK-NEXT: Successor(s): middle.block
|
|
;
|
|
entry:
|
|
br label %bb0
|
|
|
|
bb0:
|
|
%iv = phi i32 [0, %entry], [%iv.next, %bb8]
|
|
br i1 %c0, label %bb1, label %bb2
|
|
|
|
bb1:
|
|
br i1 %c1, label %bb3, label %bb4
|
|
|
|
bb2:
|
|
br label %bb6
|
|
|
|
bb3:
|
|
br i1 %c2, label %bb8, label %bb5
|
|
|
|
bb4:
|
|
br i1 %c3, label %bb5, label %bb6
|
|
|
|
bb5:
|
|
br label %bb7
|
|
|
|
bb6:
|
|
br i1 %c4, label %bb7, label %bb8
|
|
|
|
bb7:
|
|
%phi = phi i32 [0, %bb5], [1, %bb6]
|
|
%gep = getelementptr i32, ptr %p, i32 %iv
|
|
store i32 %phi, ptr %gep
|
|
br label %bb8
|
|
|
|
bb8:
|
|
%iv.next = add i32 %iv, 1
|
|
%ec = icmp eq i32 %iv.next, 128
|
|
br i1 %ec, label %exit, label %bb0
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
; bb0
|
|
; / |
|
|
; bb1 |
|
|
; | \ |
|
|
; | bb2
|
|
; | /
|
|
; bb3
|
|
;
|
|
; The blend masks for %phi in bb3 should be:
|
|
; bb0 := bb1->bb2 v bb0->bb2 := c0 && !c1 || !c0
|
|
; bb1 := bb1->bb3 := c0 && c1
|
|
define void @blend_masks_triangle_phi(ptr noalias %p, i1 %c0, i1 %c1) {
|
|
; CHECK-LABEL: VPlan for loop in 'blend_masks_triangle_phi'
|
|
; CHECK-NEXT: <x1> vector loop: {
|
|
; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = CANONICAL-IV
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: vector.body:
|
|
; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]>
|
|
; CHECK-NEXT: Successor(s): bb1
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb1:
|
|
; CHECK-NEXT: Successor(s): bb2
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb2:
|
|
; CHECK-NEXT: EMIT vp<[[VP4:%[0-9]+]]> = not ir<%c1>
|
|
; CHECK-NEXT: EMIT vp<[[VP5:%[0-9]+]]> = logical-and ir<%c0>, vp<[[VP4]]>
|
|
; CHECK-NEXT: EMIT vp<[[VP6:%[0-9]+]]> = not ir<%c0>
|
|
; CHECK-NEXT: EMIT vp<[[VP7:%[0-9]+]]> = or vp<[[VP5]]>, vp<[[VP6]]>
|
|
; CHECK-NEXT: Successor(s): bb3
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: bb3:
|
|
; CHECK-NEXT: EMIT vp<[[VP8:%[0-9]+]]> = logical-and ir<%c0>, ir<%c1>
|
|
; CHECK-NEXT: BLEND ir<%phi> = ir<1>/vp<[[VP7]]> ir<0>/vp<[[VP8]]>
|
|
; CHECK-NEXT: EMIT ir<%gep> = getelementptr ir<%p>, ir<%iv>
|
|
; CHECK-NEXT: EMIT store ir<%phi>, ir<%gep>
|
|
; CHECK-NEXT: EMIT ir<%iv.next> = add ir<%iv>, ir<1>
|
|
; CHECK-NEXT: EMIT ir<%ec> = icmp eq ir<%iv.next>, ir<128>
|
|
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, vp<[[VP1:%[0-9]+]]>
|
|
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2:%[0-9]+]]>
|
|
; CHECK-NEXT: No successors
|
|
; CHECK-NEXT: }
|
|
; CHECK-NEXT: Successor(s): middle.block
|
|
;
|
|
entry:
|
|
br label %bb0
|
|
|
|
bb0:
|
|
%iv = phi i32 [0, %entry], [%iv.next, %bb3]
|
|
br i1 %c0, label %bb1, label %bb2
|
|
|
|
bb1:
|
|
br i1 %c1, label %bb3, label %bb2
|
|
|
|
bb2:
|
|
br label %bb3
|
|
|
|
bb3:
|
|
%phi = phi i32 [0, %bb1], [1, %bb2]
|
|
%gep = getelementptr i32, ptr %p, i32 %iv
|
|
store i32 %phi, ptr %gep
|
|
%iv.next = add i32 %iv, 1
|
|
%ec = icmp eq i32 %iv.next, 128
|
|
br i1 %ec, label %exit, label %bb0
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @blend_chain_non_trivial(ptr noalias %a, ptr noalias %b) {
|
|
; CHECK-LABEL: VPlan for loop in 'blend_chain_non_trivial'
|
|
; CHECK-NEXT: <x1> vector loop: {
|
|
; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = CANONICAL-IV
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: vector.body:
|
|
; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION nuw nsw ir<0>, ir<1>, vp<[[VP0:%[0-9]+]]>
|
|
; CHECK-NEXT: EMIT-SCALAR ir<%lb> = load ir<%b>
|
|
; CHECK-NEXT: EMIT ir<%v1> = add ir<%iv>, ir<%lb>
|
|
; CHECK-NEXT: EMIT ir<%v2> = mul ir<%iv>, ir<3>
|
|
; CHECK-NEXT: EMIT ir<%gep> = getelementptr ir<%a>, ir<%iv>
|
|
; CHECK-NEXT: EMIT ir<%c0> = icmp sle ir<%iv>, ir<0>
|
|
; CHECK-NEXT: Successor(s): if.a
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: if.a:
|
|
; CHECK-NEXT: EMIT ir<%ca> = icmp sle ir<%iv>, ir<8>, ir<%c0>
|
|
; CHECK-NEXT: Successor(s): if.a.inner
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: if.a.inner:
|
|
; CHECK-NEXT: EMIT vp<[[VP4:%[0-9]+]]> = logical-and ir<%c0>, ir<%ca>
|
|
; CHECK-NEXT: Successor(s): merge.a.inner
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: merge.a.inner:
|
|
; CHECK-NEXT: Successor(s): merge.a
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: merge.a:
|
|
; CHECK-NEXT: EMIT vp<[[VP5:%[0-9]+]]> = not ir<%c0>
|
|
; CHECK-NEXT: BLEND ir<%blend.a> = ir<%v1>/ir<%c0> ir<%v1>/vp<[[VP5]]>
|
|
; CHECK-NEXT: EMIT ir<%d0> = icmp sgt ir<%iv>, ir<0>
|
|
; CHECK-NEXT: Successor(s): if.b
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: if.b:
|
|
; CHECK-NEXT: EMIT ir<%cb> = icmp sle ir<%iv>, ir<16>, ir<%d0>
|
|
; CHECK-NEXT: Successor(s): if.b.inner
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: if.b.inner:
|
|
; CHECK-NEXT: EMIT vp<[[VP6:%[0-9]+]]> = logical-and ir<%d0>, ir<%cb>
|
|
; CHECK-NEXT: Successor(s): merge.b.inner
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: merge.b.inner:
|
|
; CHECK-NEXT: Successor(s): merge.b
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: merge.b:
|
|
; CHECK-NEXT: EMIT vp<[[VP7:%[0-9]+]]> = not ir<%d0>
|
|
; CHECK-NEXT: BLEND ir<%blend.b> = ir<%v2>/ir<%d0> ir<%v2>/vp<[[VP7]]>
|
|
; CHECK-NEXT: EMIT ir<%sum> = add ir<%blend.a>, ir<%blend.b>
|
|
; CHECK-NEXT: EMIT store ir<%sum>, ir<%gep>
|
|
; CHECK-NEXT: Successor(s): loop.latch
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: loop.latch:
|
|
; CHECK-NEXT: EMIT ir<%iv.next> = add nuw nsw ir<%iv>, ir<1>
|
|
; CHECK-NEXT: EMIT ir<%ec> = icmp eq ir<%iv.next>, ir<128>
|
|
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, vp<[[VP1:%[0-9]+]]>
|
|
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2:%[0-9]+]]>
|
|
; CHECK-NEXT: No successors
|
|
; CHECK-NEXT: }
|
|
; CHECK-NEXT: Successor(s): middle.block
|
|
;
|
|
entry:
|
|
br label %loop.header
|
|
|
|
loop.header:
|
|
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
|
|
%lb = load i64, ptr %b
|
|
%v1 = add i64 %iv, %lb
|
|
%v2 = mul i64 %iv, 3
|
|
%gep = getelementptr i64, ptr %a, i64 %iv
|
|
%c0 = icmp sle i64 %iv, 0
|
|
br i1 %c0, label %if.a, label %merge.a
|
|
|
|
if.a:
|
|
%ca = icmp sle i64 %iv, 8
|
|
br i1 %ca, label %if.a.inner, label %merge.a.inner
|
|
|
|
if.a.inner:
|
|
br label %merge.a.inner
|
|
|
|
merge.a.inner:
|
|
%blend.a.inner = phi i64 [ %v1, %if.a ], [ %v1, %if.a.inner ]
|
|
br label %merge.a
|
|
|
|
merge.a:
|
|
%blend.a = phi i64 [ %v1, %loop.header ], [ %blend.a.inner, %merge.a.inner ]
|
|
%d0 = icmp sgt i64 %iv, 0
|
|
br i1 %d0, label %if.b, label %merge.b
|
|
|
|
if.b:
|
|
%cb = icmp sle i64 %iv, 16
|
|
br i1 %cb, label %if.b.inner, label %merge.b.inner
|
|
|
|
if.b.inner:
|
|
br label %merge.b.inner
|
|
|
|
merge.b.inner:
|
|
%blend.b.inner = phi i64 [ %v2, %if.b ], [ %v2, %if.b.inner ]
|
|
br label %merge.b
|
|
|
|
merge.b:
|
|
%blend.b = phi i64 [ %v2, %merge.a ], [ %blend.b.inner, %merge.b.inner ]
|
|
%sum = add i64 %blend.a, %blend.b
|
|
store i64 %sum, ptr %gep
|
|
br label %loop.latch
|
|
|
|
loop.latch:
|
|
%iv.next = add nuw nsw i64 %iv, 1
|
|
%ec = icmp eq i64 %iv.next, 128
|
|
br i1 %ec, label %exit, label %loop.header
|
|
|
|
exit:
|
|
ret void
|
|
}
|