xref: /llvm-project/llvm/test/Transforms/LoopVectorize/vplan-sink-scalars-and-merge.ll (revision 7f3428d3ed71d87a2088b77b6cab9f3d86544234)
1; REQUIRES: asserts
2
3; RUN: opt -passes=loop-vectorize -force-vector-interleave=1 -force-vector-width=2 -debug -disable-output %s 2>&1 | FileCheck %s
4
5target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
6
7@a = common global [2048 x i32] zeroinitializer, align 16
8@b = common global [2048 x i32] zeroinitializer, align 16
9@c = common global [2048 x i32] zeroinitializer, align 16
10
11
12; CHECK-LABEL: LV: Checking a loop in 'sink1'
13; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
14; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
15; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
16; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
17; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
18; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count
19; CHECK-EMPTY:
20; CHECK-NEXT: ir-bb<entry>:
21; CHECK-NEXT:   EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw>
22; CHECK-NEXT: Successor(s): vector.ph
23; CHECK-EMPTY:
24; CHECK-NEXT: vector.ph:
25; CHECK-NEXT: Successor(s): vector loop
26; CHECK-EMPTY:
27; CHECK-NEXT: <x1> vector loop: {
28; CHECK-NEXT: vector.body:
29; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
30; CHECK-NEXT:   ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]>
31; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
32; CHECK-NEXT: Successor(s): pred.store
33
34; CHECK:      <xVFxUF> pred.store: {
35; CHECK-NEXT:   pred.store.entry:
36; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
37; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
38
39; CHECK:      pred.store.if:
40; CHECK-NEXT:     vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
41; CHECK-NEXT:     REPLICATE ir<%gep.b> = getelementptr inbounds ir<@b>, ir<0>, vp<[[STEPS]]>
42; CHECK-NEXT:     REPLICATE ir<%lv.b> = load ir<%gep.b>
43; CHECK-NEXT:     REPLICATE ir<%add> = add ir<%lv.b>, ir<10>
44; CHECK-NEXT:     REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, vp<[[STEPS]]
45; CHECK-NEXT:     REPLICATE ir<%mul> = mul ir<2>, ir<%add>
46; CHECK-NEXT:     REPLICATE store ir<%mul>, ir<%gep.a>
47; CHECK-NEXT:   Successor(s): pred.store.continue
48
49; CHECK:      pred.store.continue:
50; CHECK-NEXT:   No successors
51; CHECK-NEXT: }
52
53; CHECK:      loop.1:
54; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
55; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
56; CHECK-NEXT: No successors
57; CHECK-NEXT: }
58;
59define void @sink1(i32 %k) {
60entry:
61  br label %loop
62
63loop:
64  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
65  %gep.b = getelementptr inbounds [2048 x i32], ptr @b, i32 0, i32 %iv
66  %lv.b  = load i32, ptr %gep.b, align 4
67  %add = add i32 %lv.b, 10
68  %mul = mul i32 2, %add
69  %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %iv
70  store i32 %mul, ptr %gep.a, align 4
71  %iv.next = add i32 %iv, 1
72  %large = icmp sge i32 %iv, 8
73  %exitcond = icmp eq i32 %iv, %k
74  %realexit = or i1 %large, %exitcond
75  br i1 %realexit, label %exit, label %loop
76
77exit:
78  ret void
79}
80
81; CHECK-LABEL: LV: Checking a loop in 'sink2'
82; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
83; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
84; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
85; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
86; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
87; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count
88; CHECK-EMPTY:
89; CHECK-NEXT: ir-bb<entry>:
90; CHECK-NEXT:   EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw>
91; CHECK-NEXT: Successor(s): vector.ph
92; CHECK-EMPTY:
93; CHECK-NEXT: vector.ph:
94; CHECK-NEXT: Successor(s): vector loop
95; CHECK-EMPTY:
96; CHECK-NEXT: <x1> vector loop: {
97; CHECK-NEXT: vector.body:
98; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
99; CHECK-NEXT:   ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]>
100; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
101; CHECK-NEXT: Successor(s): pred.load
102
103; CHECK:      <xVFxUF> pred.load: {
104; CHECK-NEXT:   pred.load.entry:
105; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
106; CHECK-NEXT:   Successor(s): pred.load.if, pred.load.continue
107
108; CHECK:      pred.load.if:
109; CHECK-NEXT:     vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
110; CHECK-NEXT:     REPLICATE ir<%gep.b> = getelementptr inbounds ir<@b>, ir<0>, vp<[[STEPS]]>
111; CHECK-NEXT:     REPLICATE ir<%lv.b> = load ir<%gep.b>
112; CHECK-NEXT:   Successor(s): pred.load.continue
113
114; CHECK:      pred.load.continue:
115; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv.b>
116; CHECK-NEXT:   No successors
117; CHECK-NEXT: }
118
119; CHECK:      loop.0:
120; CHECK-NEXT:   WIDEN ir<%mul> = mul ir<%iv>, ir<2>
121; CHECK-NEXT: Successor(s): pred.store
122
123; CHECK:      <xVFxUF> pred.store: {
124; CHECK-NEXT:   pred.store.entry:
125; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
126; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
127
128; CHECK:       pred.store.if:
129; CHECK-NEXT:     REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, ir<%mul>
130; CHECK-NEXT:     REPLICATE ir<%add> = add vp<[[PRED]]>, ir<10>
131; CHECK-NEXT:     REPLICATE store ir<%add>, ir<%gep.a>
132; CHECK-NEXT:   Successor(s): pred.store.continue
133
134; CHECK:      pred.store.continue:
135; CHECK-NEXT:   No successors
136; CHECK-NEXT: }
137
138; CHECK:       loop.1:
139; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
140; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
141; CHECK-NEXT: No successors
142; CHECK-NEXT: }
143;
144define void @sink2(i32 %k) {
145entry:
146  br label %loop
147
148loop:
149  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
150  %gep.b = getelementptr inbounds [2048 x i32], ptr @b, i32 0, i32 %iv
151  %lv.b  = load i32, ptr %gep.b, align 4
152  %add = add i32 %lv.b, 10
153  %mul = mul i32 %iv, 2
154  %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %mul
155  store i32 %add, ptr %gep.a, align 4
156  %iv.next = add i32 %iv, 1
157  %large = icmp sge i32 %iv, 8
158  %exitcond = icmp eq i32 %iv, %k
159  %realexit = or i1 %large, %exitcond
160  br i1 %realexit, label %exit, label %loop
161
162exit:
163  ret void
164}
165
166; CHECK-LABEL: LV: Checking a loop in 'sink3'
167; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
168; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
169; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
170; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
171; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
172; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count
173; CHECK-EMPTY:
174; CHECK-NEXT: ir-bb<entry>:
175; CHECK-NEXT:   EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw>
176; CHECK-NEXT: Successor(s): vector.ph
177; CHECK-EMPTY:
178; CHECK-NEXT: vector.ph:
179; CHECK-NEXT: Successor(s): vector loop
180; CHECK-EMPTY:
181; CHECK-NEXT: <x1> vector loop: {
182; CHECK-NEXT: vector.body:
183; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
184; CHECK-NEXT:   ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]>
185; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
186; CHECK-NEXT: Successor(s): pred.load
187
188; CHECK:      <xVFxUF> pred.load: {
189; CHECK-NEXT:   pred.load.entry:
190; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
191; CHECK-NEXT:   Successor(s): pred.load.if, pred.load.continue
192
193; CHECK:       pred.load.if:
194; CHECK-NEXT:     vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
195; CHECK-NEXT:     REPLICATE ir<%gep.b> = getelementptr inbounds ir<@b>, ir<0>, vp<[[STEPS]]>
196; CHECK-NEXT:     REPLICATE ir<%lv.b> = load ir<%gep.b> (S->V)
197; CHECK-NEXT:   Successor(s): pred.load.continue
198
199; CHECK:       pred.load.continue:
200; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv.b>
201; CHECK-NEXT:   No successors
202; CHECK-NEXT: }
203
204; CHECK:      loop.0:
205; CHECK-NEXT:   WIDEN ir<%add> = add vp<[[PRED]]>, ir<10>
206; CHECK-NEXT:   WIDEN ir<%mul> = mul ir<%iv>, ir<%add>
207; CHECK-NEXT: Successor(s): pred.store
208
209; CHECK:      <xVFxUF> pred.store: {
210; CHECK-NEXT:   pred.store.entry:
211; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
212; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
213
214; CHECK:      pred.store.if:
215; CHECK-NEXT:     REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, ir<%mul>
216; CHECK-NEXT:     REPLICATE store ir<%add>, ir<%gep.a>
217; CHECK-NEXT:   Successor(s): pred.store.continue
218
219; CHECK:      pred.store.continue:
220; CHECK-NEXT:   No successors
221; CHECK-NEXT: }
222
223; CHECK:      loop.1:
224; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
225; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
226; CHECK-NEXT: No successors
227; CHECK-NEXT: }
228;
229define void @sink3(i32 %k) {
230entry:
231  br label %loop
232
233loop:
234  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
235  %gep.b = getelementptr inbounds [2048 x i32], ptr @b, i32 0, i32 %iv
236  %lv.b  = load i32, ptr %gep.b, align 4
237  %add = add i32 %lv.b, 10
238  %mul = mul i32 %iv, %add
239  %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %mul
240  store i32 %add, ptr %gep.a, align 4
241  %iv.next = add i32 %iv, 1
242  %large = icmp sge i32 %iv, 8
243  %exitcond = icmp eq i32 %iv, %k
244  %realexit = or i1 %large, %exitcond
245  br i1 %realexit, label %exit, label %loop
246
247exit:
248  ret void
249}
250
251; Make sure we do not sink uniform instructions.
252define void @uniform_gep(i64 %k, ptr noalias %A, ptr noalias %B) {
253; CHECK-LABEL: LV: Checking a loop in 'uniform_gep'
254; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
255; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
256; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
257; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
258; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
259; CHECK-NEXT: Live-in ir<11> = original trip-count
260; CHECK-EMPTY:
261; CHECK-NEXT: ir-bb<entry>:
262; CHECK-NEXT: Successor(s): vector.ph
263; CHECK-EMPTY:
264; CHECK-NEXT: vector.ph:
265; CHECK-NEXT:   vp<[[END:%.+]]> = DERIVED-IV ir<21> + vp<[[VEC_TC]]> * ir<1>
266; CHECK-NEXT:   CLONE ir<%gep.A.uniform> = getelementptr inbounds ir<%A>, ir<0>
267; CHECK-NEXT: Successor(s): vector loop
268; CHECK-EMPTY:
269; CHECK-NEXT: <x1> vector loop: {
270; CHECK-NEXT: vector.body:
271; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
272; CHECK-NEXT:   ir<%iv> = WIDEN-INDUCTION ir<21>, ir<1>, vp<[[VF]]>
273; CHECK-NEXT:   vp<[[DERIVED_IV:%.+]]> = DERIVED-IV ir<21> + vp<[[CAN_IV]]> * ir<1>
274; CHECK-NEXT:   EMIT vp<[[WIDE_CAN_IV:%.+]]> = WIDEN-CANONICAL-INDUCTION vp<[[CAN_IV]]>
275; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule vp<[[WIDE_CAN_IV]]>, vp<[[BTC]]>
276; CHECK-NEXT:   CLONE ir<%lv> = load ir<%gep.A.uniform>
277; CHECK-NEXT:   WIDEN ir<%cmp> = icmp ult ir<%iv>, ir<%k>
278; CHECK-NEXT:   EMIT vp<[[NOT2:%.+]]> = not ir<%cmp>
279; CHECK-NEXT:   EMIT vp<[[MASK2:%.+]]> = logical-and vp<[[MASK]]>, vp<[[NOT2]]>
280; CHECK-NEXT: Successor(s): pred.store
281; CHECK-EMPTY:
282; CHECK-NEXT: <xVFxUF> pred.store: {
283; CHECK-NEXT:   pred.store.entry:
284; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK2]]>
285; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
286; CHECK-EMPTY:
287; CHECK-NEXT:   pred.store.if:
288; CHECK-NEXT:     vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[DERIVED_IV]]>, ir<1>
289; CHECK-NEXT:     REPLICATE ir<%gep.B> = getelementptr inbounds ir<%B>, vp<[[STEPS]]>
290; CHECK-NEXT:     REPLICATE store ir<%lv>, ir<%gep.B>
291; CHECK-NEXT:   Successor(s): pred.store.continue
292; CHECK-EMPTY:
293; CHECK-NEXT:   pred.store.continue:
294; CHECK-NEXT:   No successors
295; CHECK-NEXT: }
296; CHECK-NEXT: Successor(s): loop.then.0
297; CHECK-EMPTY:
298; CHECK-NEXT: loop.then.0:
299; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
300; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
301; CHECK-NEXT: No successors
302; CHECK-NEXT: }
303;
304entry:
305  br label %loop
306
307loop:
308  %iv = phi i64 [ 21, %entry ], [ %iv.next, %loop.latch ]
309  %gep.A.uniform = getelementptr inbounds i16, ptr %A, i64 0
310  %gep.B = getelementptr inbounds i16, ptr %B, i64 %iv
311  %lv = load i16, ptr %gep.A.uniform, align 1
312  %cmp = icmp ult i64 %iv, %k
313  br i1 %cmp, label %loop.latch, label %loop.then
314
315loop.then:
316  store i16 %lv, ptr %gep.B, align 1
317  br label %loop.latch
318
319loop.latch:
320  %iv.next = add nsw i64 %iv, 1
321  %cmp179 = icmp slt i64 %iv.next, 32
322  br i1 %cmp179, label %loop, label %exit
323exit:
324  ret void
325}
326
327; Loop with predicated load.
328define void @pred_cfg1(i32 %k, i32 %j) {
329; CHECK-LABEL: LV: Checking a loop in 'pred_cfg1'
330; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
331; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
332; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
333; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
334; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
335; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count
336; CHECK-EMPTY:
337; CHECK-NEXT: ir-bb<entry>:
338; CHECK-NEXT:   EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw>
339; CHECK-NEXT: Successor(s): vector.ph
340; CHECK-EMPTY:
341; CHECK-NEXT: vector.ph:
342; CHECK-NEXT: Successor(s): vector loop
343; CHECK-EMPTY:
344; CHECK-NEXT: <x1> vector loop: {
345; CHECK-NEXT: vector.body:
346; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
347; CHECK-NEXT:   ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]>
348; CHECK-NEXT:   EMIT vp<[[MASK1:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
349; CHECK-NEXT:   WIDEN ir<%c.1> = icmp ult ir<%iv>, ir<%j>
350; CHECK-NEXT:   WIDEN ir<%mul> = mul ir<%iv>, ir<10>
351; CHECK-NEXT:   EMIT vp<[[MASK2:%.+]]> = logical-and vp<[[MASK1]]>, ir<%c.1>
352; CHECK-NEXT: Successor(s): pred.load
353; CHECK-EMPTY:
354; CHECK-NEXT: <xVFxUF> pred.load: {
355; CHECK-NEXT:   pred.load.entry:
356; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK2]]>
357; CHECK-NEXT:   Successor(s): pred.load.if, pred.load.continue
358; CHECK-EMPTY:
359; CHECK-NEXT:   pred.load.if:
360; CHECK-NEXT:     vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
361; CHECK-NEXT:     REPLICATE ir<%gep.b> = getelementptr inbounds ir<@b>, ir<0>, vp<[[STEPS]]>
362; CHECK-NEXT:     REPLICATE ir<%lv.b> = load ir<%gep.b> (S->V)
363; CHECK-NEXT:   Successor(s): pred.load.continue
364; CHECK-EMPTY:
365; CHECK-NEXT:   pred.load.continue:
366; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv.b>
367; CHECK-NEXT:   No successors
368; CHECK-NEXT: }
369; CHECK-NEXT: Successor(s): then.0.0
370; CHECK-EMPTY:
371; CHECK-NEXT: then.0.0:
372; CHECK-NEXT:   BLEND ir<%p> = ir<0> vp<[[PRED]]>/vp<[[MASK2]]>
373; CHECK-NEXT: Successor(s): pred.store
374; CHECK-EMPTY:
375; CHECK-NEXT: <xVFxUF> pred.store: {
376; CHECK-NEXT:   pred.store.entry:
377; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK1]]>
378; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
379; CHECK-EMPTY:
380; CHECK-NEXT:   pred.store.if:
381; CHECK-NEXT:     REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, ir<%mul>
382; CHECK-NEXT:     REPLICATE store ir<%p>, ir<%gep.a>
383; CHECK-NEXT:   Successor(s): pred.store.continue
384; CHECK-EMPTY:
385; CHECK-NEXT:   pred.store.continue:
386; CHECK-NEXT:   No successors
387; CHECK-NEXT: }
388; CHECK-NEXT: Successor(s): next.0.1
389; CHECK-EMPTY:
390; CHECK-NEXT: next.0.1:
391; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
392; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
393; CHECK-NEXT: No successors
394; CHECK-NEXT: }
395;
396entry:
397  br label %loop
398
399loop:
400  %iv = phi i32 [ 0, %entry ], [ %iv.next, %next.0 ]
401  %gep.b = getelementptr inbounds [2048 x i32], ptr @b, i32 0, i32 %iv
402  %c.1 = icmp ult i32 %iv, %j
403  %mul = mul i32 %iv, 10
404  %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %mul
405  br i1 %c.1, label %then.0, label %next.0
406
407then.0:
408  %lv.b  = load i32, ptr %gep.b, align 4
409  br label %next.0
410
411next.0:
412  %p = phi i32 [ 0, %loop ], [ %lv.b, %then.0 ]
413  store i32 %p, ptr %gep.a, align 4
414  %iv.next = add i32 %iv, 1
415  %large = icmp sge i32 %iv, 8
416  %exitcond = icmp eq i32 %iv, %k
417  %realexit = or i1 %large, %exitcond
418  br i1 %realexit, label %exit, label %loop
419
420exit:
421  ret void
422}
423
424; Loop with predicated load and store in separate blocks, store depends on
425; loaded value.
426define void @pred_cfg2(i32 %k, i32 %j) {
427; CHECK-LABEL: LV: Checking a loop in 'pred_cfg2'
428; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
429; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
430; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
431; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
432; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
433; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count
434; CHECK-EMPTY:
435; CHECK-NEXT: ir-bb<entry>:
436; CHECK-NEXT:   EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw>
437; CHECK-NEXT: Successor(s): vector.ph
438; CHECK-EMPTY:
439; CHECK-NEXT: vector.ph:
440; CHECK-NEXT: Successor(s): vector loop
441; CHECK-EMPTY:
442; CHECK-NEXT: <x1> vector loop: {
443; CHECK-NEXT: vector.body:
444; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
445; CHECK-NEXT:   ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]>
446; CHECK-NEXT:   EMIT vp<[[MASK1:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
447; CHECK-NEXT:   WIDEN ir<%mul> = mul ir<%iv>, ir<10>
448; CHECK-NEXT:   WIDEN ir<%c.0> = icmp ult ir<%iv>, ir<%j>
449; CHECK-NEXT:   WIDEN ir<%c.1> = icmp ugt ir<%iv>, ir<%j>
450; CHECK-NEXT:   EMIT vp<[[MASK2:%.+]]> = logical-and vp<[[MASK1]]>, ir<%c.0>
451; CHECK-NEXT: Successor(s): pred.load
452; CHECK-EMPTY:
453; CHECK-NEXT: <xVFxUF> pred.load: {
454; CHECK-NEXT:   pred.load.entry:
455; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK2]]>
456; CHECK-NEXT:   Successor(s): pred.load.if, pred.load.continue
457; CHECK-EMPTY:
458; CHECK-NEXT:   pred.load.if:
459; CHECK-NEXT:     vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
460; CHECK-NEXT:     REPLICATE ir<%gep.b> = getelementptr inbounds ir<@b>, ir<0>, vp<[[STEPS]]>
461; CHECK-NEXT:     REPLICATE ir<%lv.b> = load ir<%gep.b> (S->V)
462; CHECK-NEXT:   Successor(s): pred.load.continue
463; CHECK-EMPTY:
464; CHECK-NEXT:   pred.load.continue:
465; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv.b>
466; CHECK-NEXT:   No successors
467; CHECK-NEXT: }
468; CHECK-NEXT: Successor(s): then.0.0
469; CHECK-EMPTY:
470; CHECK-NEXT: then.0.0:
471; CHECK-NEXT:   BLEND ir<%p> = ir<0> vp<[[PRED]]>/vp<[[MASK2]]>
472; CHECK-NEXT:   EMIT vp<[[MASK3:%.+]]> = logical-and vp<[[MASK1]]>, ir<%c.1>
473; CHECK-NEXT: Successor(s): pred.store
474; CHECK-EMPTY:
475; CHECK-NEXT: <xVFxUF> pred.store: {
476; CHECK-NEXT:   pred.store.entry:
477; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK3]]>
478; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
479; CHECK-EMPTY:
480; CHECK-NEXT:   pred.store.if:
481; CHECK-NEXT:     REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, ir<%mul>
482; CHECK-NEXT:     REPLICATE store ir<%p>, ir<%gep.a>
483; CHECK-NEXT:   Successor(s): pred.store.continue
484; CHECK-EMPTY:
485; CHECK-NEXT:   pred.store.continue:
486; CHECK-NEXT:   No successors
487; CHECK-NEXT: }
488; CHECK-NEXT: Successor(s): then.1.1
489; CHECK-EMPTY:
490; CHECK-NEXT: then.1.1:
491; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
492; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
493; CHECK-NEXT: No successors
494; CHECK-NEXT: }
495;
496entry:
497  br label %loop
498
499loop:
500  %iv = phi i32 [ 0, %entry ], [ %iv.next, %next.1 ]
501  %gep.b = getelementptr inbounds [2048 x i32], ptr @b, i32 0, i32 %iv
502  %mul = mul i32 %iv, 10
503  %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %mul
504  %c.0 = icmp ult i32 %iv, %j
505  %c.1 = icmp ugt i32 %iv, %j
506  br i1 %c.0, label %then.0, label %next.0
507
508then.0:
509  %lv.b  = load i32, ptr %gep.b, align 4
510  br label %next.0
511
512next.0:
513  %p = phi i32 [ 0, %loop ], [ %lv.b, %then.0 ]
514  br i1 %c.1, label %then.1, label %next.1
515
516then.1:
517  store i32 %p, ptr %gep.a, align 4
518  br label %next.1
519
520next.1:
521  %iv.next = add i32 %iv, 1
522  %large = icmp sge i32 %iv, 8
523  %exitcond = icmp eq i32 %iv, %k
524  %realexit = or i1 %large, %exitcond
525  br i1 %realexit, label %exit, label %loop
526
527exit:
528  ret void
529}
530
531; Loop with predicated load and store in separate blocks, store does not depend
532; on loaded value.
533define void @pred_cfg3(i32 %k, i32 %j) {
534; CHECK-LABEL: LV: Checking a loop in 'pred_cfg3'
535; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
536; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
537; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
538; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
539; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
540; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count
541; CHECK-EMPTY:
542; CHECK-NEXT: ir-bb<entry>:
543; CHECK-NEXT:   EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw>
544; CHECK-NEXT: Successor(s): vector.ph
545; CHECK-EMPTY:
546; CHECK-NEXT: vector.ph:
547; CHECK-NEXT: Successor(s): vector loop
548; CHECK-EMPTY:
549; CHECK-NEXT: <x1> vector loop: {
550; CHECK-NEXT: vector.body:
551; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
552; CHECK-NEXT:   ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]>
553; CHECK-NEXT:   EMIT vp<[[MASK1:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
554; CHECK-NEXT:   WIDEN ir<%mul> = mul ir<%iv>, ir<10>
555; CHECK-NEXT:   WIDEN ir<%c.0> = icmp ult ir<%iv>, ir<%j>
556; CHECK-NEXT:   EMIT vp<[[MASK2:%.+]]> = logical-and vp<[[MASK1:%.+]]>, ir<%c.0>
557; CHECK-NEXT: Successor(s): pred.load
558; CHECK-EMPTY:
559; CHECK-NEXT: <xVFxUF> pred.load: {
560; CHECK-NEXT:   pred.load.entry:
561; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK2]]>
562; CHECK-NEXT:   Successor(s): pred.load.if, pred.load.continue
563; CHECK-EMPTY:
564; CHECK-NEXT:   pred.load.if:
565; CHECK-NEXT:     vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
566; CHECK-NEXT:     REPLICATE ir<%gep.b> = getelementptr inbounds ir<@b>, ir<0>, vp<[[STEPS]]>
567; CHECK-NEXT:     REPLICATE ir<%lv.b> = load ir<%gep.b>
568; CHECK-NEXT:   Successor(s): pred.load.continue
569; CHECK-EMPTY:
570; CHECK-NEXT:   pred.load.continue:
571; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv.b>
572; CHECK-NEXT:   No successors
573; CHECK-NEXT: }
574; CHECK-NEXT: Successor(s): then.0.0
575; CHECK-EMPTY:
576; CHECK-NEXT: then.0.0:
577; CHECK-NEXT:   BLEND ir<%p> = ir<0> vp<[[PRED]]>/vp<[[MASK2]]>
578; CHECK-NEXT:   EMIT vp<[[MASK3:%.+]]> = logical-and vp<[[MASK1]]>, ir<%c.0>
579; CHECK-NEXT: Successor(s): pred.store
580; CHECK-EMPTY:
581; CHECK-NEXT: <xVFxUF> pred.store: {
582; CHECK-NEXT:   pred.store.entry:
583; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK3]]>
584; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
585; CHECK-EMPTY:
586; CHECK-NEXT:   pred.store.if:
587; CHECK-NEXT:     REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, ir<%mul>
588; CHECK-NEXT:     REPLICATE store ir<0>, ir<%gep.a>
589; CHECK-NEXT:     REPLICATE ir<%gep.c> = getelementptr inbounds ir<@c>, ir<0>, ir<%mul>
590; CHECK-NEXT:     REPLICATE store ir<%p>, ir<%gep.c>
591; CHECK-NEXT:   Successor(s): pred.store.continue
592; CHECK-EMPTY:
593; CHECK-NEXT:   pred.store.continue:
594; CHECK-NEXT:   No successors
595; CHECK-NEXT: }
596; CHECK-NEXT: Successor(s): then.1.2
597; CHECK-EMPTY:
598; CHECK-NEXT: then.1.2:
599; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
600; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
601; CHECK-NEXT: No successors
602; CHECK-NEXT: }
603;
604entry:
605  br label %loop
606
607loop:
608  %iv = phi i32 [ 0, %entry ], [ %iv.next, %next.1 ]
609  %gep.b = getelementptr inbounds [2048 x i32], ptr @b, i32 0, i32 %iv
610  %mul = mul i32 %iv, 10
611  %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %mul
612  %gep.c = getelementptr inbounds [2048 x i32], ptr @c, i32 0, i32 %mul
613  %c.0 = icmp ult i32 %iv, %j
614  br i1 %c.0, label %then.0, label %next.0
615
616then.0:
617  %lv.b  = load i32, ptr %gep.b, align 4
618  br label %next.0
619
620next.0:
621  %p = phi i32 [ 0, %loop ], [ %lv.b, %then.0 ]
622  br i1 %c.0, label %then.1, label %next.1
623
624then.1:
625  store i32 0, ptr %gep.a, align 4
626  store i32 %p, ptr %gep.c, align 4
627  br label %next.1
628
629next.1:
630  %iv.next = add i32 %iv, 1
631  %large = icmp sge i32 %iv, 8
632  %exitcond = icmp eq i32 %iv, %k
633  %realexit = or i1 %large, %exitcond
634  br i1 %realexit, label %exit, label %loop
635
636exit:
637  ret void
638}
639
640define void @merge_3_replicate_region(i32 %k, i32 %j) {
641; CHECK-LABEL: LV: Checking a loop in 'merge_3_replicate_region'
642; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
643; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
644; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
645; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
646; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
647; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count
648; CHECK-EMPTY:
649; CHECK-NEXT: ir-bb<entry>:
650; CHECK-NEXT:   EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw>
651; CHECK-NEXT: Successor(s): vector.ph
652; CHECK-EMPTY:
653; CHECK-NEXT: vector.ph:
654; CHECK-NEXT: Successor(s): vector loop
655; CHECK-EMPTY:
656; CHECK-NEXT: <x1> vector loop: {
657; CHECK-NEXT: vector.body:
658; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
659; CHECK-NEXT:   ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]>
660; CHECK-NEXT:   vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
661; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
662; CHECK-NEXT: Successor(s): pred.store
663; CHECK-EMPTY:
664; CHECK-NEXT: <xVFxUF> pred.store: {
665; CHECK-NEXT:   pred.store.entry:
666; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
667; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
668; CHECK-EMPTY:
669; CHECK-NEXT:   pred.store.if:
670; CHECK-NEXT:     REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, vp<[[STEPS]]>
671; CHECK-NEXT:     REPLICATE ir<%lv.a> = load ir<%gep.a>
672; CHECK-NEXT:     REPLICATE ir<%gep.b> = getelementptr inbounds ir<@b>, ir<0>, vp<[[STEPS]]>
673; CHECK-NEXT:     REPLICATE ir<%lv.b> = load ir<%gep.b>
674; CHECK-NEXT:     REPLICATE ir<%gep.c> = getelementptr inbounds ir<@c>, ir<0>, vp<[[STEPS]]>
675; CHECK-NEXT:     REPLICATE store ir<%lv.a>, ir<%gep.c>
676; CHECK-NEXT:     REPLICATE store ir<%lv.b>, ir<%gep.a>
677; CHECK-NEXT:   Successor(s): pred.store.continue
678; CHECK-EMPTY:
679; CHECK-NEXT:   pred.store.continue:
680; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED1:%.+]]> = ir<%lv.a>
681; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED2:%.+]]> = ir<%lv.b>
682; CHECK-NEXT:   No successors
683; CHECK-NEXT: }
684; CHECK-NEXT: Successor(s): loop.3
685; CHECK-EMPTY:
686; CHECK-NEXT: loop.3:
687; CHECK-NEXT:   WIDEN ir<%c.0> = icmp ult ir<%iv>, ir<%j>
688; CHECK-NEXT:   EMIT vp<[[MASK2:%.+]]> = logical-and vp<[[MASK]]>, ir<%c.0>
689; CHECK-NEXT:   WIDEN ir<%mul> = mul vp<[[PRED1]]>, vp<[[PRED2]]>
690; CHECK-NEXT: Successor(s): pred.store
691; CHECK-EMPTY:
692; CHECK-NEXT: <xVFxUF> pred.store: {
693; CHECK-NEXT:   pred.store.entry:
694; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK2]]>
695; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
696; CHECK-EMPTY:
697; CHECK-NEXT:   pred.store.if:
698; CHECK-NEXT:     REPLICATE ir<%gep.c.1> = getelementptr inbounds ir<@c>, ir<0>, vp<[[STEPS]]>
699; CHECK-NEXT:     REPLICATE store ir<%mul>, ir<%gep.c.1>
700; CHECK-NEXT:   Successor(s): pred.store.continue
701; CHECK-EMPTY:
702; CHECK-NEXT:   pred.store.continue:
703; CHECK-NEXT:   No successors
704; CHECK-NEXT: }
705; CHECK-NEXT: Successor(s): then.0.4
706; CHECK-EMPTY:
707; CHECK-NEXT: then.0.4:
708; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
709; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
710; CHECK-NEXT: No successors
711; CHECK-NEXT: }
712;
713entry:
714  br label %loop
715
716loop:
717  %iv = phi i32 [ 0, %entry ], [ %iv.next, %latch ]
718  %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %iv
719  %lv.a  = load i32, ptr %gep.a, align 4
720  %gep.b = getelementptr inbounds [2048 x i32], ptr @b, i32 0, i32 %iv
721  %lv.b  = load i32, ptr %gep.b, align 4
722  %gep.c = getelementptr inbounds [2048 x i32], ptr @c, i32 0, i32 %iv
723  store i32 %lv.a, ptr %gep.c, align 4
724  store i32 %lv.b, ptr %gep.a, align 4
725  %c.0 = icmp ult i32 %iv, %j
726  br i1 %c.0, label %then.0, label %latch
727
728then.0:
729  %mul = mul i32 %lv.a, %lv.b
730  %gep.c.1 = getelementptr inbounds [2048 x i32], ptr @c, i32 0, i32 %iv
731  store i32 %mul, ptr %gep.c.1, align 4
732  br label %latch
733
734latch:
735  %iv.next = add i32 %iv, 1
736  %large = icmp sge i32 %iv, 8
737  %exitcond = icmp eq i32 %iv, %k
738  %realexit = or i1 %large, %exitcond
739  br i1 %realexit, label %exit, label %loop
740
741exit:
742  ret void
743}
744
745
746define void @update_2_uses_in_same_recipe_in_merged_block(i32 %k) {
747; CHECK-LABEL: LV: Checking a loop in 'update_2_uses_in_same_recipe_in_merged_block'
748; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
749; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
750; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
751; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
752; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
753; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count
754; CHECK-EMPTY:
755; CHECK-NEXT: ir-bb<entry>:
756; CHECK-NEXT:   EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw>
757; CHECK-NEXT: Successor(s): vector.ph
758; CHECK-EMPTY:
759; CHECK-NEXT: vector.ph:
760; CHECK-NEXT: Successor(s): vector loop
761; CHECK-EMPTY:
762; CHECK-NEXT: <x1> vector loop: {
763; CHECK-NEXT: vector.body:
764; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
765; CHECK-NEXT:   ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]>
766; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
767; CHECK-NEXT: Successor(s): pred.store
768; CHECK-EMPTY:
769; CHECK-NEXT: <xVFxUF> pred.store: {
770; CHECK-NEXT:   pred.store.entry:
771; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
772; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
773; CHECK-EMPTY:
774; CHECK-NEXT:   pred.store.if:
775; CHECK-NEXT:     vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
776; CHECK-NEXT:     REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, vp<[[STEPS]]>
777; CHECK-NEXT:     REPLICATE ir<%lv.a> = load ir<%gep.a>
778; CHECK-NEXT:     REPLICATE ir<%div> = sdiv ir<%lv.a>, ir<%lv.a>
779; CHECK-NEXT:     REPLICATE store ir<%div>, ir<%gep.a>
780; CHECK-NEXT:   Successor(s): pred.store.continue
781; CHECK-EMPTY:
782; CHECK-NEXT:   pred.store.continue:
783; CHECK-NEXT:   No successors
784; CHECK-NEXT: }
785; CHECK-NEXT: Successor(s): loop.2
786; CHECK-EMPTY:
787; CHECK-NEXT: loop.2:
788; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
789; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
790; CHECK-NEXT: No successors
791; CHECK-NEXT: }
792;
793entry:
794  br label %loop
795
796loop:
797  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
798  %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %iv
799  %lv.a  = load i32, ptr %gep.a, align 4
800  %div = sdiv i32 %lv.a, %lv.a
801  store i32 %div, ptr %gep.a, align 4
802  %iv.next = add i32 %iv, 1
803  %large = icmp sge i32 %iv, 8
804  %exitcond = icmp eq i32 %iv, %k
805  %realexit = or i1 %large, %exitcond
806  br i1 %realexit, label %exit, label %loop
807
808exit:
809  ret void
810}
811
812define void @recipe_in_merge_candidate_used_by_first_order_recurrence(i32 %k) {
813; CHECK-LABEL: LV: Checking a loop in 'recipe_in_merge_candidate_used_by_first_order_recurrence'
814; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
815; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
816; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
817; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
818; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
819; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count
820; CHECK-EMPTY:
821; CHECK-NEXT: ir-bb<entry>:
822; CHECK-NEXT:   EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw>
823; CHECK-NEXT: Successor(s): vector.ph
824; CHECK-EMPTY:
825; CHECK-NEXT: vector.ph:
826; CHECK-NEXT: Successor(s): vector loop
827; CHECK-EMPTY:
828; CHECK-NEXT: <x1> vector loop: {
829; CHECK-NEXT: vector.body:
830; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
831; CHECK-NEXT:   ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VF]]>
832; CHECK-NEXT:   FIRST-ORDER-RECURRENCE-PHI ir<%for> = phi ir<0>, vp<[[PRED:%.+]]>
833; CHECK-NEXT:   vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
834; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
835; CHECK-NEXT:   REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, vp<[[STEPS]]>
836; CHECK-NEXT: Successor(s): pred.load
837; CHECK-EMPTY:
838; CHECK-NEXT: <xVFxUF> pred.load: {
839; CHECK-NEXT:   pred.load.entry:
840; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
841; CHECK-NEXT:   Successor(s): pred.load.if, pred.load.continue
842; CHECK-EMPTY:
843; CHECK-NEXT:   pred.load.if:
844; CHECK-NEXT:     REPLICATE ir<%lv.a> = load ir<%gep.a>
845; CHECK-NEXT:   Successor(s): pred.load.continue
846; CHECK-EMPTY:
847; CHECK-NEXT:   pred.load.continue:
848; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED]]> = ir<%lv.a>
849; CHECK-NEXT:   No successors
850; CHECK-NEXT: }
851; CHECK-NEXT: Successor(s): loop.0
852; CHECK-EMPTY:
853; CHECK-NEXT: loop.0:
854; CHECK-NEXT:   EMIT vp<[[SPLICE:%.+]]> = first-order splice ir<%for>, vp<[[PRED]]>
855; CHECK-NEXT: Successor(s): pred.store
856; CHECK-EMPTY:
857; CHECK-NEXT: <xVFxUF> pred.store: {
858; CHECK-NEXT:   pred.store.entry:
859; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
860; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
861; CHECK-EMPTY:
862; CHECK-NEXT:   pred.store.if:
863; CHECK-NEXT:     REPLICATE ir<%div> = sdiv vp<[[SPLICE]]>, vp<[[PRED]]>
864; CHECK-NEXT:     REPLICATE store ir<%div>, ir<%gep.a>
865; CHECK-NEXT:   Successor(s): pred.store.continue
866; CHECK-EMPTY:
867; CHECK-NEXT:   pred.store.continue:
868; CHECK-NEXT:   No successors
869; CHECK-NEXT: }
870; CHECK-NEXT: Successor(s): loop.2
871; CHECK-EMPTY:
872; CHECK-NEXT: loop.2:
873; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
874; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
875; CHECK-NEXT: No successors
876; CHECK-NEXT: }
877;
878entry:
879  br label %loop
880
881loop:
882  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
883  %for = phi i32 [ 0, %entry ], [ %lv.a, %loop ]
884  %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %iv
885  %lv.a  = load i32, ptr %gep.a, align 4
886  %div = sdiv i32 %for, %lv.a
887  store i32 %div, ptr %gep.a, align 4
888  %iv.next = add i32 %iv, 1
889  %large = icmp sge i32 %iv, 8
890  %exitcond = icmp eq i32 %iv, %k
891  %realexit = or i1 %large, %exitcond
892  br i1 %realexit, label %exit, label %loop
893
894exit:
895  ret void
896}
897
898define void @update_multiple_users(ptr noalias %src, ptr noalias %dst, i1 %c) {
899; CHECK-LABEL: LV: Checking a loop in 'update_multiple_users'
900; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
901; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
902; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
903; CHECK-NEXT: Live-in ir<999> = original trip-count
904; CHECK-EMPTY:
905; CHECK-NEXT: ir-bb<entry>:
906; CHECK-NEXT: Successor(s): vector.ph
907; CHECK-EMPTY:
908; CHECK-NEXT: vector.ph:
909; CHECK-NEXT: Successor(s): vector loop
910; CHECK-EMPTY:
911; CHECK-NEXT: <x1> vector loop: {
912; CHECK-NEXT: vector.body:
913; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
914; CHECK-NEXT: Successor(s): pred.store
915; CHECK-EMPTY:
916; CHECK-NEXT: <xVFxUF> pred.store: {
917; CHECK-NEXT:   pred.store.entry:
918; CHECK-NEXT:     BRANCH-ON-MASK ir<%c>
919; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
920; CHECK-EMPTY:
921; CHECK-NEXT:   pred.store.if:
922; CHECK-NEXT:     REPLICATE ir<%l1> = load ir<%src>
923; CHECK-NEXT:     REPLICATE ir<%l2> = trunc ir<%l1>
924; CHECK-NEXT:     REPLICATE ir<%cmp> = icmp eq ir<%l1>, ir<0>
925; CHECK-NEXT:     REPLICATE ir<%sel> = select ir<%cmp>, ir<5>, ir<%l2>
926; CHECK-NEXT:     REPLICATE store ir<%sel>, ir<%dst>
927; CHECK-NEXT:   Successor(s): pred.store.continue
928; CHECK-EMPTY:
929; CHECK-NEXT:   pred.store.continue:
930; CHECK-NEXT:   No successors
931; CHECK-NEXT: }
932; CHECK-NEXT: Successor(s): loop.then.1
933; CHECK-EMPTY:
934; CHECK-NEXT: loop.then.1:
935; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
936; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
937; CHECK-NEXT: No successors
938; CHECK-NEXT: }
939;
940entry:
941  br label %loop.header
942
943loop.header:
944  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
945  br i1 %c, label %loop.then, label %loop.latch
946
947loop.then:
948  %l1 = load i16, ptr %src, align 2
949  %l2 = trunc i16 %l1 to i8
950  %cmp = icmp eq i16 %l1, 0
951  %sel = select i1 %cmp, i8 5, i8 %l2
952  store i8 %sel, ptr %dst, align 1
953  %sext.l1 = sext i16 %l1 to i32
954  br label %loop.latch
955
956loop.latch:
957  %iv.next = add nsw i64 %iv, 1
958  %ec = icmp eq i64 %iv.next, 999
959  br i1 %ec, label %exit, label %loop.header
960
961exit:
962  ret void
963}
964
965define void @sinking_requires_duplication(ptr %addr) {
966; CHECK-LABEL: LV: Checking a loop in 'sinking_requires_duplication'
967; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
968; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
969; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
970; CHECK-NEXT: Live-in ir<201> = original trip-count
971; CHECK-EMPTY:
972; CHECK-NEXT: ir-bb<entry>:
973; CHECK-NEXT: Successor(s): vector.ph
974; CHECK-EMPTY:
975; CHECK-NEXT: vector.ph:
976; CHECK-NEXT: Successor(s): vector loop
977; CHECK-EMPTY:
978; CHECK-NEXT: <x1> vector loop: {
979; CHECK-NEXT: vector.body:
980; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
981; CHECK-NEXT:   vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
982; CHECK-NEXT:   CLONE ir<%gep> = getelementptr ir<%addr>, vp<[[STEPS]]>
983; CHECK-NEXT:   vp<[[VEC_PTR:%.+]]> = vector-pointer ir<%gep>
984; CHECK-NEXT:   WIDEN ir<%0> = load vp<[[VEC_PTR]]>
985; CHECK-NEXT:   WIDEN ir<%pred> = fcmp oeq ir<%0>, ir<0.000000e+00>
986; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = not ir<%pred>
987; CHECK-NEXT: Successor(s): pred.store
988; CHECK-EMPTY:
989; CHECK-NEXT: <xVFxUF> pred.store: {
990; CHECK-NEXT:   pred.store.entry:
991; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
992; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
993; CHECK-EMPTY:
994; CHECK-NEXT:   pred.store.if:
995; CHECK-NEXT:     REPLICATE ir<%gep>.1 = getelementptr ir<%addr>, vp<[[STEPS]]>
996; CHECK-NEXT:     REPLICATE store ir<1.000000e+01>, ir<%gep>.1
997; CHECK-NEXT:   Successor(s): pred.store.continue
998; CHECK-EMPTY:
999; CHECK-NEXT:   pred.store.continue:
1000; CHECK-NEXT:   No successors
1001; CHECK-NEXT: }
1002; CHECK-NEXT: Successor(s): then.0
1003; CHECK-EMPTY:
1004; CHECK-NEXT: then.0:
1005; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
1006; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
1007; CHECK-NEXT: No successors
1008; CHECK-NEXT: }
1009;
1010entry:
1011  br label %loop.header
1012
1013loop.header:
1014  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
1015  %gep = getelementptr float, ptr %addr, i64 %iv
1016  %exitcond.not = icmp eq i64 %iv, 200
1017  br i1 %exitcond.not, label %exit, label %loop.body
1018
1019loop.body:
1020  %0 = load float, ptr %gep, align 4
1021  %pred = fcmp oeq float %0, 0.0
1022  br i1 %pred, label %loop.latch, label %then
1023
1024then:
1025  store float 10.0, ptr %gep, align 4
1026  br label %loop.latch
1027
1028loop.latch:
1029  %iv.next = add nuw nsw i64 %iv, 1
1030  br label %loop.header
1031
1032exit:
1033  ret void
1034}
1035
1036; Test case with a dead GEP between the load and store regions. Dead recipes
1037; need to be removed before merging.
1038define void @merge_with_dead_gep_between_regions(i32 %n, ptr noalias %src, ptr noalias %dst) optsize {
1039; CHECK-LABEL: LV: Checking a loop in 'merge_with_dead_gep_between_regions'
1040; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
1041; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
1042; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
1043; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
1044; CHECK-NEXT: Live-in ir<%n> = original trip-count
1045; CHECK-EMPTY:
1046; CHECK-NEXT: ir-bb<entry>:
1047; CHECK-NEXT: Successor(s): vector.ph
1048; CHECK-EMPTY:
1049; CHECK-NEXT: vector.ph:
1050; CHECK-NEXT:   vp<[[END:%.+]]> = DERIVED-IV ir<%n> + vp<[[VEC_TC]]> * ir<-1>
1051; CHECK-NEXT: Successor(s): vector loop
1052; CHECK-EMPTY:
1053; CHECK-NEXT: <x1> vector loop: {
1054; CHECK-NEXT:   vector.body:
1055; CHECK-NEXT:     EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
1056; CHECK-NEXT:     vp<[[DERIVED_IV:%.+]]> = DERIVED-IV ir<%n> + vp<[[CAN_IV]]> * ir<-1>
1057; CHECK-NEXT:     EMIT vp<[[WIDE_IV:%.+]]> = WIDEN-CANONICAL-INDUCTION vp<[[CAN_IV]]>
1058; CHECK-NEXT:     EMIT vp<[[MASK:%.+]]> = icmp ule vp<[[WIDE_IV]]>, vp<[[BTC]]>
1059; CHECK-NEXT:   Successor(s): pred.store
1060; CHECK-EMPTY:
1061; CHECK-NEXT:   <xVFxUF> pred.store: {
1062; CHECK-NEXT:     pred.store.entry:
1063; CHECK-NEXT:       BRANCH-ON-MASK vp<[[MASK]]>
1064; CHECK-NEXT:     Successor(s): pred.store.if, pred.store.continue
1065; CHECK-EMPTY:
1066; CHECK-NEXT:     pred.store.if:
1067; CHECK-NEXT:       vp<[[SCALAR_STEPS:%.+]]>    = SCALAR-STEPS vp<[[DERIVED_IV]]>, ir<-1>
1068; CHECK-NEXT:       REPLICATE ir<%gep.src> = getelementptr inbounds ir<%src>, vp<[[SCALAR_STEPS]]>
1069; CHECK-NEXT:       REPLICATE ir<%l> = load ir<%gep.src>
1070; CHECK-NEXT:       REPLICATE ir<%gep.dst> = getelementptr inbounds ir<%dst>, vp<[[SCALAR_STEPS]]>
1071; CHECK-NEXT:       REPLICATE store ir<%l>, ir<%gep.dst>
1072; CHECK-NEXT:     Successor(s): pred.store.continue
1073; CHECK-EMPTY:
1074; CHECK-NEXT:     pred.store.continue:
1075; CHECK-NEXT:     No successors
1076; CHECK-NEXT:   }
1077; CHECK-NEXT:   Successor(s): loop.1
1078; CHECK-EMPTY:
1079; CHECK-NEXT:   loop.1:
1080; CHECK-NEXT:     EMIT vp<[[CAN_IV_NEXT:%.+]]> = add vp<[[CAN_IV]]>, vp<[[VFxUF]]>
1081; CHECK-NEXT:     EMIT branch-on-count  vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
1082; CHECK-NEXT:   No successors
1083; CHECK-NEXT: }
1084; CHECK-NEXT: Successor(s): middle.block
1085; CHECK-EMPTY:
1086; CHECK-NEXT: middle.block:
1087; CHECK-NEXT:   EMIT branch-on-cond ir<true>
1088; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph
1089; CHECK-EMPTY:
1090; CHECK-NEXT: scalar.ph
1091; CHECK-NEXT:   EMIT vp<[[RESUME:%.+]]> = resume-phi vp<[[END]]>, ir<%n>
1092; CHECK-NEXT: Successor(s): ir-bb<loop>
1093; CHECK-EMPTY:
1094; CHECK-NEXT: ir-bb<loop>:
1095; CHECK-NEXT:   IR   %iv = phi i32 [ %n, %entry ], [ %iv.next, %loop ] (extra operand: vp<[[RESUME]]> from scalar.ph)
1096; CHECK-NEXT:   IR   %iv.next = add nsw i32 %iv, -1
1097; CHECK-NEXT:   IR   %gep.src = getelementptr inbounds i32, ptr %src, i32 %iv
1098; CHECK-NEXT:   IR   %l = load i32, ptr %gep.src, align 16
1099; CHECK-NEXT:   IR   %dead_gep = getelementptr inbounds i32, ptr %dst, i64 1
1100; CHECK-NEXT:   IR   %gep.dst = getelementptr inbounds i32, ptr %dst, i32 %iv
1101; CHECK-NEXT:   IR   store i32 %l, ptr %gep.dst, align 16
1102; CHECK-NEXT:   IR   %ec = icmp eq i32 %iv.next, 0
1103; CHECK-NEXT: No successors
1104; CHECK-EMPTY:
1105; CHECK-NEXT: ir-bb<exit>
1106; CHECK-NEXT: No successors
1107; CHECK-NEXT: }
1108;
1109entry:
1110  br label %loop
1111
1112loop:
1113  %iv = phi i32[ %n, %entry ], [ %iv.next, %loop ]
1114  %iv.next = add nsw i32 %iv, -1
1115  %gep.src = getelementptr inbounds i32, ptr %src, i32 %iv
1116  %l = load i32, ptr %gep.src, align 16
1117  %dead_gep = getelementptr inbounds i32, ptr %dst, i64 1
1118  %gep.dst = getelementptr inbounds i32, ptr %dst, i32 %iv
1119  store i32 %l, ptr %gep.dst, align 16
1120  %ec = icmp eq i32 %iv.next, 0
1121  br i1 %ec, label %exit, label %loop
1122
1123exit:
1124  ret void
1125}
1126
1127define void @ptr_induction_remove_dead_recipe(ptr %start, ptr %end) {
1128; CHECK-LABEL: LV: Checking a loop in 'ptr_induction_remove_dead_recipe'
1129; CHECK:       VPlan 'Initial VPlan for VF={2},UF>=1' {
1130; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
1131; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
1132; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
1133; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count
1134; CHECK-EMPTY:
1135; CHECK-NEXT: ir-bb<entry>:
1136; CHECK-NEXT:  EMIT vp<[[TC]]> = EXPAND SCEV ((-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %start to i64))
1137; CHECK-NEXT: Successor(s): vector.ph
1138; CHECK-EMPTY:
1139; CHECK-NEXT: vector.ph:
1140; CHECK-NEXT:   vp<[[END:%.+]]> = DERIVED-IV ir<%start> + vp<[[VEC_TC]]> * ir<-1>
1141; CHECK-NEXT: Successor(s): vector loop
1142; CHECK-EMPTY:
1143; CHECK-NEXT: <x1> vector loop: {
1144; CHECK-NEXT:   vector.body:
1145; CHECK-NEXT:     EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
1146; CHECK-NEXT:     vp<[[DEV_IV:%.+]]> = DERIVED-IV ir<0> + vp<[[CAN_IV]]> * ir<-1>
1147; CHECK-NEXT:     vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[DEV_IV]]>, ir<-1>
1148; CHECK-NEXT:     EMIT vp<[[PTR_IV:%.+]]> = ptradd ir<%start>, vp<[[STEPS]]>
1149; CHECK-NEXT:     CLONE ir<%ptr.iv.next> = getelementptr inbounds vp<[[PTR_IV]]>, ir<-1>
1150; CHECK-NEXT:     vp<[[VEC_PTR:%.+]]> = reverse-vector-pointer inbounds ir<%ptr.iv.next>, vp<[[VF]]>
1151; CHECK-NEXT:     WIDEN ir<%l> = load vp<[[VEC_PTR]]>
1152; CHECK-NEXT:     WIDEN ir<%c.1> = icmp eq ir<%l>, ir<0>
1153; CHECK-NEXT:     EMIT vp<[[NEG:%.+]]> = not ir<%c.1>
1154; CHECK-NEXT:   Successor(s): pred.store
1155; CHECK-EMPTY:
1156; CHECK-NEXT:   <xVFxUF> pred.store: {
1157; CHECK-NEXT:     pred.store.entry:
1158; CHECK-NEXT:       BRANCH-ON-MASK vp<[[NEG]]>
1159; CHECK-NEXT:     Successor(s): pred.store.if, pred.store.continue
1160; CHECK-EMPTY:
1161; CHECK-NEXT:     pred.store.if:
1162; CHECK-NEXT:       REPLICATE ir<%ptr.iv.next>.1 = getelementptr inbounds vp<[[PTR_IV]]>, ir<-1>
1163; CHECK-NEXT:       REPLICATE store ir<95>, ir<%ptr.iv.next>.1
1164; CHECK-NEXT:     Successor(s): pred.store.continue
1165; CHECK-EMPTY:
1166; CHECK-NEXT:     pred.store.continue:
1167; CHECK-NEXT:     No successors
1168; CHECK-NEXT:   }
1169; CHECK-NEXT:   Successor(s): if.then.0
1170; CHECK-EMPTY:
1171; CHECK-NEXT:   if.then.0:
1172; CHECK-NEXT:     EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
1173; CHECK-NEXT:     EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
1174; CHECK-NEXT:   No successors
1175; CHECK-NEXT: }
1176; CHECK-NEXT: Successor(s): middle.block
1177; CHECK-EMPTY:
1178; CHECK-NEXT: middle.block:
1179; CHECK-NEXT:   EMIT vp<[[CMP:%.+]]> = icmp eq vp<[[TC]]>, vp<[[VEC_TC]]>
1180; CHECK-NEXT:   EMIT branch-on-cond vp<[[CMP]]>
1181; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph
1182; CHECK-EMPTY:
1183; CHECK-NEXT: scalar.ph:
1184; CHECK-NEXT:   EMIT vp<[[RESUME:%.+]]> = resume-phi vp<[[END]]>, ir<%start>
1185; CHECK-NEXT: Successor(s): ir-bb<loop.header>
1186; CHECK-EMPTY:
1187; CHECK-NEXT: ir-bb<loop.header>:
1188; CHECK-NEXT:   IR   %ptr.iv = phi ptr [ %start, %entry ], [ %ptr.iv.next, %loop.latch ] (extra operand: vp<[[RESUME]]> from scalar.ph)
1189; CHECK-NEXT:   IR   %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 -1
1190; CHECK-NEXT:   IR   %l = load i8, ptr %ptr.iv.next, align 1
1191; CHECK-NEXT:   IR   %c.1 = icmp eq i8 %l, 0
1192; CHECK-NEXT: No successors
1193; CHECK-EMPTY:
1194; CHECK-NEXT: ir-bb<exit>:
1195; CHECK-NEXT: No successors
1196; CHECK-NEXT: }
1197;
1198entry:
1199  br label %loop.header
1200
1201loop.header:
1202  %ptr.iv = phi ptr [ %start, %entry ], [ %ptr.iv.next, %loop.latch ]
1203  %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 -1
1204  %l = load i8, ptr %ptr.iv.next, align 1
1205  %c.1 = icmp eq i8 %l, 0
1206  br i1 %c.1, label %loop.latch, label %if.then
1207
1208if.then:
1209  store i8 95, ptr %ptr.iv.next, align 1
1210  br label %loop.latch
1211
1212loop.latch:
1213  %c.2 = icmp eq ptr %ptr.iv.next, %end
1214  br i1 %c.2, label %exit, label %loop.header
1215
1216exit:
1217  ret void
1218}
1219