xref: /llvm-project/llvm/test/Transforms/LoopVectorize/vplan-predicate-switch.ll (revision 7f3428d3ed71d87a2088b77b6cab9f3d86544234)
1; REQUIRES: asserts
2; RUN: opt -p loop-vectorize -force-vector-width=2 -force-vector-interleave=1 -debug -disable-output %s 2>&1 | FileCheck %s
3
4define void @switch4_default_common_dest_with_case(ptr %start, ptr %end) {
5; CHECK:      VPlan 'Final VPlan for VF={2},UF={1}' {
6; CHECK-NEXT: Live-in ir<[[VFxUF:.+]]> = VF * UF
7; CHECK-NEXT: Live-in ir<[[VTC:%.+]]> = vector-trip-count
8; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count
9; CHECK-EMPTY:
10; CHECK-NEXT: ir-bb<entry>:
11; CHECK-NEXT:   EMIT vp<[[TC]]> = EXPAND SCEV ((-1 * (ptrtoint ptr %start to i64)) + (ptrtoint ptr %end to i64))
12; CHECK-NEXT: Successor(s): ir-bb<scalar.ph>, ir-bb<vector.ph>
13; CHECK-EMPTY:
14; CHECK-NEXT: ir-bb<vector.ph>:
15; CHECK-NEXT:   IR %n.mod.vf = urem i64 %0, 2
16; CHECK-NEXT:   IR %n.vec = sub i64 %0, %n.mod.vf
17; CHECK-NEXT:   vp<[[END:%.+]]> = DERIVED-IV ir<%start> + ir<%n.vec> * ir<1>
18; CHECK-NEXT: Successor(s): vector loop
19; CHECK-EMPTY:
20; CHECK-NEXT: <x1> vector loop: {
21; CHECK-NEXT:   vector.body:
22; CHECK-NEXT:     SCALAR-PHI vp<[[CAN_IV:%.+]]> = phi ir<0>, vp<[[CAN_IV_NEXT:%.+]]>
23; CHECK-NEXT:     vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
24; CHECK-NEXT:     EMIT vp<[[PTR:%.+]]> = ptradd ir<%start>, vp<[[STEPS]]>
25; CHECK-NEXT:     vp<[[WIDE_PTR:%.+]]> = vector-pointer vp<[[PTR]]>
26; CHECK-NEXT:     WIDEN ir<%l> = load vp<[[WIDE_PTR]]>
27; CHECK-NEXT:     EMIT vp<[[C1:%.+]]> = icmp eq ir<%l>, ir<-12>
28; CHECK-NEXT:     EMIT vp<[[C2:%.+]]> = icmp eq ir<%l>, ir<13>
29; CHECK-NEXT:     EMIT vp<[[OR_CASES:%.+]]> = or vp<[[C1]]>, vp<[[C2]]>
30; CHECK-NEXT:     EMIT vp<[[DEFAULT_MASK:%.+]]> = not vp<[[OR_CASES]]>
31; CHECK-NEXT:   Successor(s): pred.store
32; CHECK-EMPTY:
33; CHECK-NEXT:   <xVFxUF> pred.store: {
34; CHECK-NEXT:     pred.store.entry:
35; CHECK-NEXT:       BRANCH-ON-MASK vp<[[C2]]>
36; CHECK-NEXT:     Successor(s): pred.store.if, pred.store.continue
37; CHECK-EMPTY:
38; CHECK-NEXT:     pred.store.if:
39; CHECK-NEXT:       REPLICATE store ir<0>, vp<[[PTR]]>
40; CHECK-NEXT:     Successor(s): pred.store.continue
41; CHECK-EMPTY:
42; CHECK-NEXT:     pred.store.continue:
43; CHECK-NEXT:     No successors
44; CHECK-NEXT:   }
45; CHECK-NEXT:   Successor(s): if.then.2.0
46; CHECK-EMPTY:
47; CHECK-NEXT:   if.then.2.0:
48; CHECK-NEXT:   Successor(s): pred.store
49; CHECK-EMPTY:
50; CHECK-NEXT:   <xVFxUF> pred.store: {
51; CHECK-NEXT:     pred.store.entry:
52; CHECK-NEXT:       BRANCH-ON-MASK vp<[[C1]]>
53; CHECK-NEXT:     Successor(s): pred.store.if, pred.store.continue
54; CHECK-EMPTY:
55; CHECK-NEXT:     pred.store.if:
56; CHECK-NEXT:       REPLICATE store ir<42>, vp<[[PTR]]>
57; CHECK-NEXT:     Successor(s): pred.store.continue
58; CHECK-EMPTY:
59; CHECK-NEXT:     pred.store.continue:
60; CHECK-NEXT:     No successors
61; CHECK-NEXT:   }
62; CHECK-NEXT:   Successor(s): if.then.1.1
63; CHECK-EMPTY:
64; CHECK-NEXT:   if.then.1.1:
65; CHECK-NEXT:   Successor(s): pred.store
66; CHECK-EMPTY:
67; CHECK-NEXT:   <xVFxUF> pred.store: {
68; CHECK-NEXT:     pred.store.entry:
69; CHECK-NEXT:       BRANCH-ON-MASK vp<[[DEFAULT_MASK]]>
70; CHECK-NEXT:     Successor(s): pred.store.if, pred.store.continue
71; CHECK-EMPTY:
72; CHECK-NEXT:     pred.store.if:
73; CHECK-NEXT:       REPLICATE store ir<2>, vp<[[PTR]]>
74; CHECK-NEXT:     Successor(s): pred.store.continue
75; CHECK-EMPTY:
76; CHECK-NEXT:     pred.store.continue:
77; CHECK-NEXT:     No successors
78; CHECK-NEXT:   }
79; CHECK-NEXT:   Successor(s): default.2
80; CHECK-EMPTY:
81; CHECK-NEXT:   default.2:
82; CHECK-NEXT:     EMIT vp<[[CAN_IV_NEXT]]> = add nuw vp<[[CAN_IV]]>, ir<[[VFxUF]]>
83; CHECK-NEXT:     EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, ir<[[VTC]]>
84; CHECK-NEXT:   No successors
85; CHECK-NEXT: }
86; CHECK-NEXT: Successor(s): ir-bb<middle.block>
87; CHECK-EMPTY:
88; CHECK-NEXT: ir-bb<middle.block>:
89; CHECK-NEXT:   EMIT vp<[[MIDDLE_CMP:%.+]]> = icmp eq vp<[[TC]]>, ir<[[VTC]]>
90; CHECK-NEXT:   EMIT branch-on-cond vp<[[MIDDLE_CMP]]>
91; CHECK-NEXT: Successor(s): ir-bb<exit>, ir-bb<scalar.ph>
92; CHECK-EMPTY:
93; CHECK-NEXT: ir-bb<exit>:
94; CHECK-NEXT: No successors
95; CHECK-EMPTY:
96; CHECK-NEXT: ir-bb<scalar.ph>:
97; CHECK-NEXT:   EMIT vp<[[RESUME:%.+]]> = resume-phi vp<[[END]]>, ir<%start>
98; CHECK-NEXT: Successor(s): ir-bb<loop.header>
99; CHECK-EMPTY:
100; CHECK-NEXT: ir-bb<loop.header>:
101; CHECK-NEXT:   IR   %ptr.iv = phi ptr [ %start, %scalar.ph ], [ %ptr.iv.next, %loop.latch ] (extra operand: vp<[[RESUME]]> from ir-bb<scalar.ph>)
102; CHECK-NEXT:   IR   %l = load i8, ptr %ptr.iv, align 1
103; CHECK-NEXT: No successors
104; CHECK-NEXT: }
105;
106entry:
107  br label %loop.header
108
109loop.header:
110  %ptr.iv = phi ptr [ %start, %entry ], [ %ptr.iv.next, %loop.latch ]
111  %l = load i8, ptr %ptr.iv, align 1
112  switch i8 %l, label %default [
113  i8 -12, label %if.then.1
114  i8 13, label %if.then.2
115  i8 0, label %default
116  ]
117
118if.then.1:
119  store i8 42, ptr %ptr.iv, align 1
120  br label %loop.latch
121
122if.then.2:
123  store i8 0, ptr %ptr.iv, align 1
124  br label %loop.latch
125
126default:
127  store i8 2, ptr %ptr.iv, align 1
128  br label %loop.latch
129
130loop.latch:
131  %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 1
132  %ec = icmp eq ptr %ptr.iv.next, %end
133  br i1 %ec, label %exit, label %loop.header
134
135exit:
136  ret void
137}
138