1; REQUIRES: asserts
2; RUN: opt < %s -passes=loop-vectorize -force-vector-width=2 -force-vector-interleave=1 -disable-output -debug-only=loop-vectorize 2>&1 | FileCheck %s
3
4target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
5
6; Test cases for PR50009, which require sinking a replicate-region due to a
7; first-order recurrence.
8
9define void @sink_replicate_region_1(i32 %x, i8* %ptr) optsize {
10; CHECK-LABEL: sink_replicate_region_1
11; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
12; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
13; CHECK-EMPTY:
14; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
15; CHECK-EMPTY:
16; CHECK-NEXT: vector.ph:
17; CHECK-NEXT: Successor(s): vector loop
18; CHECK-EMPTY:
19; CHECK-NEXT: <x1> vector loop: {
20; CHECK-NEXT: vector.body:
21; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
22; CHECK-NEXT:   FIRST-ORDER-RECURRENCE-PHI ir<%0> = phi ir<0>, ir<%conv>
23; CHECK-NEXT:   WIDEN-INDUCTION %iv = phi 0, %iv.next, ir<1>
24; CHECK-NEXT:   vp<[[STEPS:%.]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<0>, ir<1>
25; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv> vp<[[BTC]]>
26; CHECK-NEXT: Successor(s): loop.0
27; CHECK-EMPTY:
28; CHECK-NEXT: loop.0:
29; CHECK-NEXT: Successor(s): pred.load
30; CHECK-EMPTY:
31; CHECK-NEXT: <xVFxUF> pred.load: {
32; CHECK-NEXT:   pred.load.entry:
33; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
34; CHECK-NEXT:   Successor(s): pred.load.if, pred.load.continue
35; CHECK-EMPTY:
36; CHECK-NEXT:   pred.load.if:
37; CHECK-NEXT:     REPLICATE ir<%gep> = getelementptr ir<%ptr>, vp<[[STEPS]]>
38; CHECK-NEXT:     REPLICATE ir<%lv> = load ir<%gep> (S->V)
39; CHECK-NEXT:   Successor(s): pred.load.continue
40; CHECK-EMPTY:
41; CHECK-NEXT:   pred.load.continue:
42; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED1:%.+]]> = ir<%lv>
43; CHECK-NEXT:   No successors
44; CHECK-NEXT: }
45; CHECK-NEXT: Successor(s): loop.1
46; CHECK-EMPTY:
47; CHECK-NEXT: loop.1:
48; CHECK-NEXT:   WIDEN ir<%conv> = sext vp<[[PRED1]]>
49; CHECK-NEXT:   EMIT vp<[[SPLICE:%.+]]> = first-order splice ir<%0> ir<%conv>
50; CHECK-NEXT: Successor(s): pred.srem
51; CHECK-EMPTY:
52; CHECK-NEXT: <xVFxUF> pred.srem: {
53; CHECK-NEXT:   pred.srem.entry:
54; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
55; CHECK-NEXT:   Successor(s): pred.srem.if, pred.srem.continue
56; CHECK-EMPTY:
57; CHECK-NEXT:   pred.srem.if:
58; CHECK-NEXT:     REPLICATE ir<%rem> = srem vp<[[SPLICE]]>, ir<%x> (S->V)
59; CHECK-NEXT:   Successor(s): pred.srem.continue
60; CHECK-EMPTY:
61; CHECK-NEXT:   pred.srem.continue:
62; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED2:%.+]]> = ir<%rem>
63; CHECK-NEXT:   No successors
64; CHECK-NEXT: }
65; CHECK-NEXT: Successor(s): loop.1.split
66; CHECK-EMPTY:
67; CHECK-NEXT: loop.1.split:
68; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = VF * UF + vp<[[CAN_IV]]>
69; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]> vp<[[VEC_TC]]>
70; CHECK-NEXT: No successors
71; CHECK-NEXT: }
72; CHECK-NEXT: Successor(s): middle.block
73; CHECK-EMPTY:
74; CHECK-NEXT: middle.block:
75; CHECK-NEXT: No successors
76; CHECK-NEXT: }
77;
78entry:
79  br label %loop
80
81loop:
82  %0 = phi i32 [ 0, %entry ], [ %conv, %loop ]
83  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
84  %rem = srem i32 %0, %x
85  %gep = getelementptr i8, i8* %ptr, i32 %iv
86  %lv = load i8, i8* %gep
87  %conv = sext i8 %lv to i32
88  %add = add i32 %conv, %rem
89  %iv.next = add nsw i32 %iv, 1
90  %ec = icmp eq i32 %iv.next, 20001
91  br i1 %ec, label %exit, label %loop
92
93exit:
94  ret void
95}
96
97define void @sink_replicate_region_2(i32 %x, i8 %y, i32* %ptr) optsize {
98; CHECK-LABEL: sink_replicate_region_2
99; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
100; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
101; CHECK-EMPTY:
102; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
103; CHECK-EMPTY:
104; CHECK-NEXT: vector.ph:
105; CHECK-NEXT: Successor(s): vector loop
106; CHECK-EMPTY:
107; CHECK-NEXT: <x1> vector loop: {
108; CHECK-NEXT: vector.body:
109; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
110; CHECK-NEXT:   FIRST-ORDER-RECURRENCE-PHI ir<%recur> = phi ir<0>, ir<%recur.next>
111; CHECK-NEXT:   WIDEN-INDUCTION %iv = phi 0, %iv.next, ir<1>
112; CHECK-NEXT:   vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<0>, ir<1>
113; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv> vp<[[BTC]]>
114; CHECK-NEXT: Successor(s): loop.0
115; CHECK-EMPTY:
116; CHECK-NEXT: loop.0:
117; CHECK-NEXT:   WIDEN ir<%recur.next> = sext ir<%y>
118; CHECK-NEXT:   EMIT vp<[[SPLICE:%.+]]> = first-order splice ir<%recur> ir<%recur.next>
119; CHECK-NEXT: Successor(s): loop.0.split
120; CHECK-EMPTY:
121; CHECK-NEXT: loop.0.split:
122; CHECK-NEXT:   Successor(s): pred.store
123; CHECK-EMPTY:
124; CHECK-NEXT: <xVFxUF> pred.store: {
125; CHECK-NEXT:  pred.store.entry:
126; CHECK-NEXT:    BRANCH-ON-MASK vp<[[MASK]]>
127; CHECK-NEXT:  Successor(s): pred.store.if, pred.store.continue
128; CHECK-EMPTY:
129; CHECK-NEXT:  pred.store.if:
130; CHECK-NEXT:     REPLICATE ir<%rem> = srem vp<[[SPLICE]]>, ir<%x>
131; CHECK-NEXT:     REPLICATE ir<%add> = add ir<%rem>, ir<%recur.next>
132; CHECK-NEXT:     REPLICATE ir<%gep> = getelementptr ir<%ptr>, vp<[[STEPS]]>
133; CHECK-NEXT:     REPLICATE store ir<%add>, ir<%gep>
134; CHECK-NEXT:   Successor(s): pred.store.continue
135; CHECK-EMPTY:
136; CHECK-NEXT:   pred.store.continue:
137; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%rem>
138; CHECK-NEXT:   No successors
139; CHECK-NEXT: }
140; CHECK-NEXT: Successor(s): loop.1
141; CHECK-EMPTY:
142; CHECK-NEXT: loop.1:
143; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = VF * UF + vp<[[CAN_IV]]>
144; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]> vp<[[VEC_TC]]>
145; CHECK-NEXT: No successors
146; CHECK-NEXT: }
147; CHECK-NEXT: Successor(s): middle.block
148; CHECK-EMPTY:
149; CHECK-NEXT: middle.block:
150; CHECK-NEXT: No successors
151; CHECK-NEXT: }
152;
153entry:
154  br label %loop
155
156loop:
157  %recur = phi i32 [ 0, %entry ], [ %recur.next, %loop ]
158  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
159  %rem = srem i32 %recur, %x
160  %recur.next = sext i8 %y to i32
161  %add = add i32 %rem, %recur.next
162  %gep = getelementptr i32, i32* %ptr, i32 %iv
163  store i32 %add, i32* %gep
164  %iv.next = add nsw i32 %iv, 1
165  %ec = icmp eq i32 %iv.next, 20001
166  br i1 %ec, label %exit, label %loop
167
168exit:
169  ret void
170}
171
172define i32 @sink_replicate_region_3_reduction(i32 %x, i8 %y, i32* %ptr) optsize {
173; CHECK-LABEL: sink_replicate_region_3_reduction
174; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
175; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
176; CHECK-EMPTY:
177; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
178; CHECK-EMPTY:
179; CHECK-NEXT: vector.ph:
180; CHECK-NEXT: Successor(s): vector loop
181; CHECK-EMPTY:
182; CHECK-NEXT: <x1> vector loop: {
183; CHECK-NEXT: vector.body:
184; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
185; CHECK-NEXT:   FIRST-ORDER-RECURRENCE-PHI ir<%recur> = phi ir<0>, ir<%recur.next>
186; CHECK-NEXT:   WIDEN-REDUCTION-PHI ir<%and.red> = phi ir<1234>, ir<%and.red.next>
187; CHECK-NEXT:   EMIT vp<[[WIDEN_CAN:%.+]]> = WIDEN-CANONICAL-INDUCTION vp<[[CAN_IV]]>
188; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule vp<[[WIDEN_CAN]]> vp<[[BTC]]>
189; CHECK-NEXT: Successor(s): loop.0
190; CHECK-EMPTY:
191; CHECK-NEXT: loop.0:
192; CHECK-NEXT:   WIDEN ir<%recur.next> = sext ir<%y>
193; CHECK-NEXT:   EMIT vp<[[SPLICE:%.+]]> = first-order splice ir<%recur> ir<%recur.next>
194; CHECK-NEXT: Successor(s): pred.srem
195; CHECK-EMPTY:
196; CHECK-NEXT: <xVFxUF> pred.srem: {
197; CHECK-NEXT:   pred.srem.entry:
198; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
199; CHECK-NEXT:   Successor(s): pred.srem.if, pred.srem.continue
200; CHECK-EMPTY:
201; CHECK-NEXT:   pred.srem.if:
202; CHECK-NEXT:     REPLICATE ir<%rem> = srem vp<[[SPLICE]]>, ir<%x> (S->V)
203; CHECK-NEXT:   Successor(s): pred.srem.continue
204; CHECK-EMPTY:
205; CHECK-NEXT:   pred.srem.continue:
206; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%rem>
207; CHECK-NEXT:   No successors
208; CHECK-NEXT: }
209; CHECK-NEXT: Successor(s): loop.0.split
210; CHECK-EMPTY:
211; CHECK-NEXT: loop.0.split:
212; CHECK-NEXT:   WIDEN ir<%add> = add vp<[[PRED]]>, ir<%recur.next>
213; CHECK-NEXT:   WIDEN ir<%and.red.next> = and ir<%and.red>, ir<%add>
214; CHECK-NEXT:   EMIT vp<[[SEL:%.+]]> = select vp<[[MASK]]> ir<%and.red.next> ir<%and.red>
215; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = VF * UF + vp<[[CAN_IV]]>
216; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]> vp<[[VEC_TC]]>
217; CHECK-NEXT: No successors
218; CHECK-NEXT: }
219; CHECK-NEXT: Successor(s): middle.block
220; CHECK-EMPTY:
221; CHECK-NEXT: middle.block:
222; CHECK-NEXT: No successors
223; CHECK-EMPTY:
224; CHECK-NEXT: Live-out i32 %res = ir<%and.red.next>
225; CHECK-NEXT: }
226;
227entry:
228  br label %loop
229
230loop:
231  %recur = phi i32 [ 0, %entry ], [ %recur.next, %loop ]
232  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
233  %and.red = phi i32 [ 1234, %entry ], [ %and.red.next, %loop ]
234  %rem = srem i32 %recur, %x
235  %recur.next = sext i8 %y to i32
236  %add = add i32 %rem, %recur.next
237  %and.red.next = and i32 %and.red, %add
238  %iv.next = add nsw i32 %iv, 1
239  %ec = icmp eq i32 %iv.next, 20001
240  br i1 %ec, label %exit, label %loop
241
242exit:
243  %res = phi i32 [ %and.red.next, %loop ]
244  ret i32 %res
245}
246
247; To sink the replicate region containing %rem, we need to split the block
248; containing %conv at the end, because %conv is the last recipe in the block.
249define void @sink_replicate_region_4_requires_split_at_end_of_block(i32 %x, i8* %ptr) optsize {
250; CHECK-LABEL: sink_replicate_region_4_requires_split_at_end_of_block
251; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
252; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
253; CHECK-EMPTY:
254; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
255; CHECK-EMPTY:
256; CHECK-NEXT: vector.ph:
257; CHECK-NEXT: Successor(s): vector loop
258; CHECK-EMPTY:
259; CHECK-NEXT: <x1> vector loop: {
260; CHECK-NEXT: vector.body:
261; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
262; CHECK-NEXT:   FIRST-ORDER-RECURRENCE-PHI ir<%0> = phi ir<0>, ir<%conv>
263; CHECK-NEXT:   WIDEN-INDUCTION %iv = phi 0, %iv.next, ir<1>
264; CHECK-NEXT:   vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<0>, ir<1>
265; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv> vp<[[BTC]]>
266; CHECK-NEXT:   REPLICATE ir<%gep> = getelementptr ir<%ptr>, vp<[[STEPS]]>
267; CHECK-NEXT: Successor(s): loop.0
268; CHECK-EMPTY:
269; CHECK-NEXT: loop.0:
270; CHECK-NEXT: Successor(s): pred.load
271; CHECK-EMPTY:
272; CHECK-NEXT: <xVFxUF> pred.load: {
273; CHECK-NEXT:   pred.load.entry:
274; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
275; CHECK-NEXT:   Successor(s): pred.load.if, pred.load.continue
276; CHECK-EMPTY:
277; CHECK-NEXT:   pred.load.if:
278; CHECK-NEXT:     REPLICATE ir<%lv> = load ir<%gep> (S->V)
279; CHECK-NEXT:   Successor(s): pred.load.continue
280; CHECK-EMPTY:
281; CHECK-NEXT:   pred.load.continue:
282; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv>
283; CHECK-NEXT:   No successors
284; CHECK-NEXT: }
285; CHECK-NEXT: Successor(s): loop.1
286; CHECK-EMPTY:
287; CHECK-NEXT: loop.1:
288; CHECK-NEXT:   WIDEN ir<%conv> = sext vp<[[PRED]]>
289; CHECK-NEXT:   EMIT vp<[[SPLICE:%.+]]> = first-order splice ir<%0> ir<%conv>
290; CHECK-NEXT: Successor(s): loop.1.split
291
292; CHECK:      loop.1.split:
293; CHECK-NEXT: Successor(s): pred.load
294
295; CHECK:      <xVFxUF> pred.load: {
296; CHECK-NEXT:   pred.load.entry:
297; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
298; CHECK-NEXT:   Successor(s): pred.load.if, pred.load.continue
299
300; CHECK:        pred.load.if:
301; CHECK-NEXT:     REPLICATE ir<%rem> = srem vp<[[SPLICE]]>, ir<%x> (S->V)
302; CHECK-NEXT:     REPLICATE ir<%lv.2> = load ir<%gep> (S->V)
303; CHECK-NEXT:   Successor(s): pred.load.continue
304
305; CHECK:        pred.load.continue:
306; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED1:%.+]]> = ir<%rem>
307; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED2:%.+]]> = ir<%lv.2>
308; CHECK-NEXT:   No successors
309; CHECK-NEXT: }
310
311; CHECK:      loop.2:
312; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = VF * UF + vp<[[CAN_IV]]>
313; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]> vp<[[VEC_TC]]>
314; CHECK-NEXT: No successors
315; CHECK-NEXT: }
316; CHECK-NEXT: Successor(s): middle.block
317; CHECK-EMPTY:
318; CHECK-NEXT: middle.block:
319; CHECK-NEXT: No successors
320; CHECK-NEXT: }
321;
322entry:
323  br label %loop
324
325loop:
326  %0 = phi i32 [ 0, %entry ], [ %conv, %loop ]
327  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
328  %gep = getelementptr i8, i8* %ptr, i32 %iv
329  %rem = srem i32 %0, %x
330  %lv = load i8, i8* %gep
331  %conv = sext i8 %lv to i32
332  %lv.2 = load i8, i8* %gep
333  %add.1 = add i32 %conv, %rem
334  %conv.lv.2 = sext i8 %lv.2 to i32
335  %add = add i32 %add.1, %conv.lv.2
336  %iv.next = add nsw i32 %iv, 1
337  %ec = icmp eq i32 %iv.next, 20001
338  br i1 %ec, label %exit, label %loop
339
340exit:
341  ret void
342}
343
344; Test case that requires sinking a recipe in a replicate region after another replicate region.
345define void @sink_replicate_region_after_replicate_region(i32* %ptr, i32 %x, i8 %y) optsize {
346; CHECK-LABEL: sink_replicate_region_after_replicate_region
347; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
348; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
349; CHECK-EMPTY:
350; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
351; CHECK-EMPTY:
352; CHECK-NEXT: vector.ph:
353; CHECK-NEXT: Successor(s): vector loop
354; CHECK-EMPTY:
355; CHECK-NEXT: <x1> vector loop: {
356; CHECK-NEXT: vector.body:
357; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
358; CHECK-NEXT:   FIRST-ORDER-RECURRENCE-PHI ir<%recur> = phi ir<0>, ir<%recur.next>
359; CHECK-NEXT:   WIDEN-INDUCTION %iv = phi 0, %iv.next, ir<1>
360; CHECK-NEXT:   vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<0>, ir<1>
361; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv> vp<[[BTC]]>
362; CHECK-NEXT: Successor(s): loop.0
363; CHECK-EMPTY:
364; CHECK-NEXT: loop.0:
365; CHECK-NEXT: Successor(s): loop.1
366; CHECK-EMPTY:
367; CHECK-NEXT:  loop.1:
368; CHECK-NEXT:   WIDEN ir<%recur.next> = sext ir<%y>
369; CHECK-NEXT:   EMIT vp<[[SPLICE:%.+]]> = first-order splice ir<%recur> ir<%recur.next>
370; CHECK-NEXT: Successor(s): pred.srem
371; CHECK-EMPTY:
372; CHECK-NEXT: <xVFxUF> pred.srem: {
373; CHECK-NEXT:   pred.srem.entry:
374; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
375; CHECK-NEXT:   Successor(s): pred.srem.if, pred.srem.continue
376; CHECK-EMPTY:
377; CHECK-NEXT:   pred.srem.if:
378; CHECK-NEXT:     REPLICATE ir<%rem> = srem vp<[[SPLICE]]>, ir<%x>
379; CHECK-NEXT:   Successor(s): pred.srem.continue
380; CHECK-EMPTY:
381; CHECK-NEXT:   pred.srem.continue:
382; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%rem>
383; CHECK-NEXT:   No successors
384; CHECK-NEXT: }
385; CHECK-NEXT: Successor(s): loop.1.split
386; CHECK-EMPTY:
387; CHECK-NEXT: loop.1.split:
388; CHECK-NEXT: Successor(s): pred.store
389; CHECK-EMPTY:
390; CHECK-NEXT: <xVFxUF> pred.store: {
391; CHECK-NEXT:   pred.store.entry:
392; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
393; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
394; CHECK-EMPTY:
395; CHECK-NEXT:   pred.store.if:
396; CHECK-NEXT:     REPLICATE ir<%rem.div> = sdiv ir<20>, vp<[[PRED]]>
397; CHECK-NEXT:     REPLICATE ir<%gep> = getelementptr ir<%ptr>, vp<[[STEPS]]>
398; CHECK-NEXT:     REPLICATE store ir<%rem.div>, ir<%gep>
399; CHECK-NEXT:   Successor(s): pred.store.continue
400; CHECK-EMPTY:
401; CHECK-NEXT:   pred.store.continue:
402; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED2:%.+]]> = ir<%rem.div>
403; CHECK-NEXT:   No successors
404; CHECK-NEXT: }
405; CHECK-NEXT: Successor(s): loop.2
406; CHECK-EMPTY:
407; CHECK-NEXT: loop.2:
408; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = VF * UF + vp<[[CAN_IV]]>
409; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]> vp<[[VEC_TC]]>
410; CHECK-NEXT: No successors
411; CHECK-NEXT: }
412; CHECK-NEXT: Successor(s): middle.block
413; CHECK-EMPTY:
414; CHECK-NEXT: middle.block:
415; CHECK-NEXT: No successors
416; CHECK-NEXT: }
417;
418entry:
419  br label %loop
420
421loop:                                             ; preds = %loop, %entry
422  %recur = phi i32 [ 0, %entry ], [ %recur.next, %loop ]
423  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
424  %rem = srem i32 %recur, %x
425  %rem.div = sdiv i32 20, %rem
426  %recur.next = sext i8 %y to i32
427  %gep = getelementptr i32, i32* %ptr, i32 %iv
428  store i32 %rem.div, i32* %gep
429  %iv.next = add nsw i32 %iv, 1
430  %C = icmp sgt i32 %iv.next, %recur.next
431  br i1 %C, label %exit, label %loop
432
433exit:                                             ; preds = %loop
434  ret void
435}
436
437define void @need_new_block_after_sinking_pr56146(i32 %x, i32* %src) {
438; CHECK-LABEL: need_new_block_after_sinking_pr56146
439; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
440; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
441; CHECK-EMPTY:
442; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
443; CHECK-EMPTY:
444; CHECK-NEXT: vector.ph:
445; CHECK-NEXT: Successor(s): vector loop
446; CHECK-EMPTY:
447; CHECK-NEXT: <x1> vector loop: {
448; CHECK-NEXT:   vector.body:
449; CHECK-NEXT:     EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
450; CHECK-NEXT:     FIRST-ORDER-RECURRENCE-PHI ir<%.pn> = phi ir<0>, vp<[[P_L:%.+]]>
451; CHECK-NEXT:     EMIT vp<[[WIDE_IV:%.+]]> = WIDEN-CANONICAL-INDUCTION vp<[[CAN_IV]]>
452; CHECK-NEXT:     EMIT vp<[[CMP:%.+]]> = icmp ule vp<[[WIDE_IV]]> vp<[[BTC]]>
453; CHECK-NEXT:   Successor(s): loop.0
454; CHECK-EMPTY:
455; CHECK-NEXT:   loop.0:
456; CHECK-NEXT:   Successor(s): pred.load
457; CHECK-EMPTY:
458; CHECK-NEXT:   <xVFxUF> pred.load: {
459; CHECK-NEXT:     pred.load.entry:
460; CHECK-NEXT:       BRANCH-ON-MASK vp<[[CMP]]>
461; CHECK-NEXT:     Successor(s): pred.load.if, pred.load.continue
462; CHECK-EMPTY:
463; CHECK-NEXT:     pred.load.if:
464; CHECK-NEXT:       REPLICATE ir<%l> = load ir<%src> (S->V)
465; CHECK-NEXT:     Successor(s): pred.load.continue
466; CHECK-EMPTY:
467; CHECK-NEXT:     pred.load.continue:
468; CHECK-NEXT:       PHI-PREDICATED-INSTRUCTION vp<[[P_L]]> = ir<%l>
469; CHECK-NEXT:     No successors
470; CHECK-NEXT:   }
471; CHECK-NEXT:   Successor(s): pred.load.succ
472; CHECK-EMPTY:
473; CHECK-NEXT:   pred.load.succ:
474; CHECK-NEXT:     EMIT vp<[[SPLICE:%.+]]> = first-order splice ir<%.pn> vp<[[P_L]]>
475; CHECK-NEXT:   Successor(s): pred.sdiv
476; CHECK-EMPTY:
477; CHECK-NEXT:   <xVFxUF> pred.sdiv: {
478; CHECK-NEXT:     pred.sdiv.entry:
479; CHECK-NEXT:       BRANCH-ON-MASK vp<[[CMP]]>
480; CHECK-NEXT:     Successor(s): pred.sdiv.if, pred.sdiv.continue
481; CHECK-EMPTY:
482; CHECK-NEXT:     pred.sdiv.if:
483; CHECK-NEXT:       REPLICATE ir<%val> = sdiv vp<[[SPLICE]]>, ir<%x>
484; CHECK-NEXT:     Successor(s): pred.sdiv.continue
485; CHECK-EMPTY:
486; CHECK-NEXT:     pred.sdiv.continue:
487; CHECK-NEXT:       PHI-PREDICATED-INSTRUCTION vp<[[P_VAL:%.+]]> = ir<%val>
488; CHECK-NEXT:     No successors
489; CHECK-NEXT:   }
490; CHECK-NEXT:   Successor(s): loop.1
491; CHECK-EMPTY:
492; CHECK-NEXT:   loop.1:
493; CHECK-NEXT:     EMIT vp<[[CAN_IV_NEXT:%.+]]> = VF * UF +  vp<[[CAN_IV]]>
494; CHECK-NEXT:     EMIT branch-on-count  vp<[[CAN_IV_NEXT]]> vp<[[VEC_TC]]>
495; CHECK-NEXT:   No successors
496; CHECK-NEXT: }
497; CHECK-NEXT: Successor(s): middle.block
498; CHECK-EMPTY:
499; CHECK-NEXT: middle.block:
500; CHECK-NEXT: No successors
501; CHECK-NEXT: }
502;
503entry:
504  br label %loop
505
506loop:
507  %iv = phi i64 [ 2, %entry ], [ %iv.next, %loop ]
508  %.pn = phi i32 [ 0, %entry ], [ %l, %loop ]
509  %val = sdiv i32 %.pn, %x
510  %l = load i32, i32* %src, align 4
511  %iv.next = add nuw nsw i64 %iv, 1
512  %ec = icmp ugt i64 %iv, 3
513  br i1 %ec, label %exit, label %loop
514
515exit:
516  ret void
517}
518