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-NEXT:   CondBit: vp<[[MASK]]> (vector.body)
36; CHECK-EMPTY:
37; CHECK-NEXT:   pred.load.if:
38; CHECK-NEXT:     REPLICATE ir<%gep> = getelementptr ir<%ptr>, vp<[[STEPS]]>
39; CHECK-NEXT:     REPLICATE ir<%lv> = load ir<%gep> (S->V)
40; CHECK-NEXT:   Successor(s): pred.load.continue
41; CHECK-EMPTY:
42; CHECK-NEXT:   pred.load.continue:
43; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED1:%.+]]> = ir<%lv>
44; CHECK-NEXT:   No successors
45; CHECK-NEXT: }
46; CHECK-NEXT: Successor(s): loop.1
47; CHECK-EMPTY:
48; CHECK-NEXT: loop.1:
49; CHECK-NEXT:   WIDEN ir<%conv> = sext vp<[[PRED1]]>
50; CHECK-NEXT:   EMIT vp<[[SPLICE:%.+]]> = first-order splice ir<%0> ir<%conv>
51; CHECK-NEXT: Successor(s): pred.srem
52; CHECK-EMPTY:
53; CHECK-NEXT: <xVFxUF> pred.srem: {
54; CHECK-NEXT:   pred.srem.entry:
55; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
56; CHECK-NEXT:   Successor(s): pred.srem.if, pred.srem.continue
57; CHECK-NEXT:   CondBit: vp<[[MASK]]> (vector.body)
58; CHECK-EMPTY:
59; CHECK-NEXT:   pred.srem.if:
60; CHECK-NEXT:     REPLICATE ir<%rem> = srem vp<[[SPLICE]]>, ir<%x> (S->V)
61; CHECK-NEXT:   Successor(s): pred.srem.continue
62; CHECK-EMPTY:
63; CHECK-NEXT:   pred.srem.continue:
64; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED2:%.+]]> = ir<%rem>
65; CHECK-NEXT:   No successors
66; CHECK-NEXT: }
67; CHECK-NEXT: Successor(s): loop.1.split
68; CHECK-EMPTY:
69; CHECK-NEXT: loop.1.split:
70; CHECK-NEXT:   WIDEN ir<%add> = add ir<%conv>, vp<[[PRED2]]>
71; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = VF * UF + vp<[[CAN_IV]]>
72; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]> vp<[[VEC_TC]]>
73; CHECK-NEXT: No successors
74; CHECK-NEXT: }
75; CHECK-NEXT: Successor(s): middle.block
76; CHECK-EMPTY:
77; CHECK-NEXT: middle.block:
78; CHECK-NEXT: No successors
79; CHECK-NEXT: }
80;
81entry:
82  br label %loop
83
84loop:
85  %0 = phi i32 [ 0, %entry ], [ %conv, %loop ]
86  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
87  %rem = srem i32 %0, %x
88  %gep = getelementptr i8, i8* %ptr, i32 %iv
89  %lv = load i8, i8* %gep
90  %conv = sext i8 %lv to i32
91  %add = add i32 %conv, %rem
92  %iv.next = add nsw i32 %iv, 1
93  %ec = icmp eq i32 %iv.next, 20001
94  br i1 %ec, label %exit, label %loop
95
96exit:
97  ret void
98}
99
100define void @sink_replicate_region_2(i32 %x, i8 %y, i32* %ptr) optsize {
101; CHECK-LABEL: sink_replicate_region_2
102; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
103; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
104; CHECK-EMPTY:
105; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
106; CHECK-EMPTY:
107; CHECK-NEXT: vector.ph:
108; CHECK-NEXT: Successor(s): vector loop
109; CHECK-EMPTY:
110; CHECK-NEXT: <x1> vector loop: {
111; CHECK-NEXT: vector.body:
112; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
113; CHECK-NEXT:   FIRST-ORDER-RECURRENCE-PHI ir<%recur> = phi ir<0>, ir<%recur.next>
114; CHECK-NEXT:   WIDEN-INDUCTION %iv = phi 0, %iv.next, ir<1>
115; CHECK-NEXT:   vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<0>, ir<1>
116; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv> vp<[[BTC]]>
117; CHECK-NEXT: Successor(s): loop.0
118; CHECK-EMPTY:
119; CHECK-NEXT: loop.0:
120; CHECK-NEXT:   WIDEN ir<%recur.next> = sext ir<%y>
121; CHECK-NEXT:   EMIT vp<[[SPLICE:%.+]]> = first-order splice ir<%recur> ir<%recur.next>
122; CHECK-NEXT: Successor(s): loop.0.split
123; CHECK-EMPTY:
124; CHECK-NEXT: loop.0.split:
125; CHECK-NEXT:   Successor(s): pred.store
126; CHECK-EMPTY:
127; CHECK-NEXT: <xVFxUF> pred.store: {
128; CHECK-NEXT:  pred.store.entry:
129; CHECK-NEXT:    BRANCH-ON-MASK vp<[[MASK]]>
130; CHECK-NEXT:  Successor(s): pred.store.if, pred.store.continue
131; CHECK-NEXT:  CondBit: vp<[[MASK]]> (vector.body)
132; CHECK-EMPTY:
133; CHECK-NEXT:  pred.store.if:
134; CHECK-NEXT:     REPLICATE ir<%rem> = srem vp<[[SPLICE]]>, ir<%x>
135; CHECK-NEXT:     REPLICATE ir<%add> = add ir<%rem>, ir<%recur.next>
136; CHECK-NEXT:     REPLICATE ir<%gep> = getelementptr ir<%ptr>, vp<[[STEPS]]>
137; CHECK-NEXT:     REPLICATE store ir<%add>, ir<%gep>
138; CHECK-NEXT:   Successor(s): pred.store.continue
139; CHECK-EMPTY:
140; CHECK-NEXT:   pred.store.continue:
141; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%rem>
142; CHECK-NEXT:   No successors
143; CHECK-NEXT: }
144; CHECK-NEXT: Successor(s): loop.1
145; CHECK-EMPTY:
146; CHECK-NEXT: loop.1:
147; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = VF * UF + vp<[[CAN_IV]]>
148; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]> vp<[[VEC_TC]]>
149; CHECK-NEXT: No successors
150; CHECK-NEXT: }
151; CHECK-NEXT: Successor(s): middle.block
152; CHECK-EMPTY:
153; CHECK-NEXT: middle.block:
154; CHECK-NEXT: No successors
155; CHECK-NEXT: }
156;
157entry:
158  br label %loop
159
160loop:
161  %recur = phi i32 [ 0, %entry ], [ %recur.next, %loop ]
162  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
163  %rem = srem i32 %recur, %x
164  %recur.next = sext i8 %y to i32
165  %add = add i32 %rem, %recur.next
166  %gep = getelementptr i32, i32* %ptr, i32 %iv
167  store i32 %add, i32* %gep
168  %iv.next = add nsw i32 %iv, 1
169  %ec = icmp eq i32 %iv.next, 20001
170  br i1 %ec, label %exit, label %loop
171
172exit:
173  ret void
174}
175
176define i32 @sink_replicate_region_3_reduction(i32 %x, i8 %y, i32* %ptr) optsize {
177; CHECK-LABEL: sink_replicate_region_3_reduction
178; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
179; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
180; CHECK-EMPTY:
181; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
182; CHECK-EMPTY:
183; CHECK-NEXT: vector.ph:
184; CHECK-NEXT: Successor(s): vector loop
185; CHECK-EMPTY:
186; CHECK-NEXT: <x1> vector loop: {
187; CHECK-NEXT: vector.body:
188; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
189; CHECK-NEXT:   FIRST-ORDER-RECURRENCE-PHI ir<%recur> = phi ir<0>, ir<%recur.next>
190; CHECK-NEXT:   WIDEN-REDUCTION-PHI ir<%and.red> = phi ir<1234>, ir<%and.red.next>
191; CHECK-NEXT:   EMIT vp<[[WIDEN_CAN:%.+]]> = WIDEN-CANONICAL-INDUCTION vp<[[CAN_IV]]>
192; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule vp<[[WIDEN_CAN]]> vp<[[BTC]]>
193; CHECK-NEXT: Successor(s): loop.0
194; CHECK-EMPTY:
195; CHECK-NEXT: loop.0:
196; CHECK-NEXT:   WIDEN ir<%recur.next> = sext ir<%y>
197; CHECK-NEXT:   EMIT vp<[[SPLICE:%.+]]> = first-order splice ir<%recur> ir<%recur.next>
198; CHECK-NEXT: Successor(s): pred.srem
199; CHECK-EMPTY:
200; CHECK-NEXT: <xVFxUF> pred.srem: {
201; CHECK-NEXT:   pred.srem.entry:
202; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
203; CHECK-NEXT:   Successor(s): pred.srem.if, pred.srem.continue
204; CHECK-NEXT:   CondBit: vp<[[MASK]]> (vector.body)
205; CHECK-EMPTY:
206; CHECK-NEXT:   pred.srem.if:
207; CHECK-NEXT:     REPLICATE ir<%rem> = srem vp<[[SPLICE]]>, ir<%x> (S->V)
208; CHECK-NEXT:   Successor(s): pred.srem.continue
209; CHECK-EMPTY:
210; CHECK-NEXT:   pred.srem.continue:
211; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%rem>
212; CHECK-NEXT:   No successors
213; CHECK-NEXT: }
214; CHECK-NEXT: Successor(s): loop.0.split
215; CHECK-EMPTY:
216; CHECK-NEXT: loop.0.split:
217; CHECK-NEXT:   WIDEN ir<%add> = add vp<[[PRED]]>, ir<%recur.next>
218; CHECK-NEXT:   WIDEN ir<%and.red.next> = and ir<%and.red>, ir<%add>
219; CHECK-NEXT:   EMIT vp<[[SEL:%.+]]> = select vp<[[MASK]]> ir<%and.red.next> ir<%and.red>
220; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = VF * UF + vp<[[CAN_IV]]>
221; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]> vp<[[VEC_TC]]>
222; CHECK-NEXT: No successors
223; CHECK-NEXT: }
224; CHECK-NEXT: Successor(s): middle.block
225; CHECK-EMPTY:
226; CHECK-NEXT: middle.block:
227; CHECK-NEXT: No successors
228; CHECK-EMPTY:
229; CHECK-NEXT: Live-out i32 %res = ir<%and.red.next>
230; CHECK-NEXT: }
231;
232entry:
233  br label %loop
234
235loop:
236  %recur = phi i32 [ 0, %entry ], [ %recur.next, %loop ]
237  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
238  %and.red = phi i32 [ 1234, %entry ], [ %and.red.next, %loop ]
239  %rem = srem i32 %recur, %x
240  %recur.next = sext i8 %y to i32
241  %add = add i32 %rem, %recur.next
242  %and.red.next = and i32 %and.red, %add
243  %iv.next = add nsw i32 %iv, 1
244  %ec = icmp eq i32 %iv.next, 20001
245  br i1 %ec, label %exit, label %loop
246
247exit:
248  %res = phi i32 [ %and.red.next, %loop ]
249  ret i32 %res
250}
251
252; To sink the replicate region containing %rem, we need to split the block
253; containing %conv at the end, because %conv is the last recipe in the block.
254define void @sink_replicate_region_4_requires_split_at_end_of_block(i32 %x, i8* %ptr) optsize {
255; CHECK-LABEL: sink_replicate_region_4_requires_split_at_end_of_block
256; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
257; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
258; CHECK-EMPTY:
259; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
260; CHECK-EMPTY:
261; CHECK-NEXT: vector.ph:
262; CHECK-NEXT: Successor(s): vector loop
263; CHECK-EMPTY:
264; CHECK-NEXT: <x1> vector loop: {
265; CHECK-NEXT: vector.body:
266; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
267; CHECK-NEXT:   FIRST-ORDER-RECURRENCE-PHI ir<%0> = phi ir<0>, ir<%conv>
268; CHECK-NEXT:   WIDEN-INDUCTION %iv = phi 0, %iv.next, ir<1>
269; CHECK-NEXT:   vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<0>, ir<1>
270; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv> vp<[[BTC]]>
271; CHECK-NEXT:   REPLICATE ir<%gep> = getelementptr ir<%ptr>, vp<[[STEPS]]>
272; CHECK-NEXT: Successor(s): loop.0
273; CHECK-EMPTY:
274; CHECK-NEXT: loop.0:
275; CHECK-NEXT: Successor(s): pred.load
276; CHECK-EMPTY:
277; CHECK-NEXT: <xVFxUF> pred.load: {
278; CHECK-NEXT:   pred.load.entry:
279; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
280; CHECK-NEXT:   Successor(s): pred.load.if, pred.load.continue
281; CHECK-NEXT:   CondBit: vp<[[MASK]]> (vector.body)
282; CHECK-EMPTY:
283; CHECK-NEXT:   pred.load.if:
284; CHECK-NEXT:     REPLICATE ir<%lv> = load ir<%gep> (S->V)
285; CHECK-NEXT:   Successor(s): pred.load.continue
286; CHECK-EMPTY:
287; CHECK-NEXT:   pred.load.continue:
288; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv>
289; CHECK-NEXT:   No successors
290; CHECK-NEXT: }
291; CHECK-NEXT: Successor(s): loop.1
292; CHECK-EMPTY:
293; CHECK-NEXT: loop.1:
294; CHECK-NEXT:   WIDEN ir<%conv> = sext vp<[[PRED]]>
295; CHECK-NEXT:   EMIT vp<[[SPLICE:%.+]]> = first-order splice ir<%0> ir<%conv>
296; CHECK-NEXT: Successor(s): loop.1.split
297
298; CHECK:      loop.1.split:
299; CHECK-NEXT: Successor(s): pred.load
300
301; CHECK:      <xVFxUF> pred.load: {
302; CHECK-NEXT:   pred.load.entry:
303; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
304; CHECK-NEXT:   Successor(s): pred.load.if, pred.load.continue
305; CHECK-NEXT:   CondBit: vp<[[MASK]]> (vector.body)
306
307; CHECK:        pred.load.if:
308; CHECK-NEXT:     REPLICATE ir<%rem> = srem vp<[[SPLICE]]>, ir<%x> (S->V)
309; CHECK-NEXT:     REPLICATE ir<%lv.2> = load ir<%gep> (S->V)
310; CHECK-NEXT:   Successor(s): pred.load.continue
311
312; CHECK:        pred.load.continue:
313; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED1:%.+]]> = ir<%rem>
314; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED2:%.+]]> = ir<%lv.2>
315; CHECK-NEXT:   No successors
316; CHECK-NEXT: }
317
318; CHECK:      loop.2:
319; CHECK-NEXT:   WIDEN ir<%add.1> = add ir<%conv>, vp<[[PRED1]]>
320; CHECK-NEXT:   WIDEN ir<%conv.lv.2> = sext vp<[[PRED2]]>
321; CHECK-NEXT:   WIDEN ir<%add> = add ir<%add.1>, ir<%conv.lv.2>
322; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = VF * UF + vp<[[CAN_IV]]>
323; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]> vp<[[VEC_TC]]>
324; CHECK-NEXT: No successors
325; CHECK-NEXT: }
326; CHECK-NEXT: Successor(s): middle.block
327; CHECK-EMPTY:
328; CHECK-NEXT: middle.block:
329; CHECK-NEXT: No successors
330; CHECK-NEXT: }
331;
332entry:
333  br label %loop
334
335loop:
336  %0 = phi i32 [ 0, %entry ], [ %conv, %loop ]
337  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
338  %gep = getelementptr i8, i8* %ptr, i32 %iv
339  %rem = srem i32 %0, %x
340  %lv = load i8, i8* %gep
341  %conv = sext i8 %lv to i32
342  %lv.2 = load i8, i8* %gep
343  %add.1 = add i32 %conv, %rem
344  %conv.lv.2 = sext i8 %lv.2 to i32
345  %add = add i32 %add.1, %conv.lv.2
346  %iv.next = add nsw i32 %iv, 1
347  %ec = icmp eq i32 %iv.next, 20001
348  br i1 %ec, label %exit, label %loop
349
350exit:
351  ret void
352}
353
354; Test case that requires sinking a recipe in a replicate region after another replicate region.
355define void @sink_replicate_region_after_replicate_region(i32* %ptr, i32 %x, i8 %y) optsize {
356; CHECK-LABEL: sink_replicate_region_after_replicate_region
357; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
358; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
359; CHECK-EMPTY:
360; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
361; CHECK-EMPTY:
362; CHECK-NEXT: vector.ph:
363; CHECK-NEXT: Successor(s): vector loop
364; CHECK-EMPTY:
365; CHECK-NEXT: <x1> vector loop: {
366; CHECK-NEXT: vector.body:
367; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
368; CHECK-NEXT:   FIRST-ORDER-RECURRENCE-PHI ir<%recur> = phi ir<0>, ir<%recur.next>
369; CHECK-NEXT:   WIDEN-INDUCTION %iv = phi 0, %iv.next, ir<1>
370; CHECK-NEXT:   vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<0>, ir<1>
371; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv> vp<[[BTC]]>
372; CHECK-NEXT: Successor(s): loop.0
373; CHECK-EMPTY:
374; CHECK-NEXT: loop.0:
375; CHECK-NEXT: Successor(s): loop.1
376; CHECK-EMPTY:
377; CHECK-NEXT:  loop.1:
378; CHECK-NEXT:   WIDEN ir<%recur.next> = sext ir<%y>
379; CHECK-NEXT:   EMIT vp<[[SPLICE:%.+]]> = first-order splice ir<%recur> ir<%recur.next>
380; CHECK-NEXT: Successor(s): pred.srem
381; CHECK-EMPTY:
382; CHECK-NEXT: <xVFxUF> pred.srem: {
383; CHECK-NEXT:   pred.srem.entry:
384; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
385; CHECK-NEXT:   Successor(s): pred.srem.if, pred.srem.continue
386; CHECK-NEXT:   CondBit: vp<[[MASK]]> (vector.body)
387; CHECK-EMPTY:
388; CHECK-NEXT:   pred.srem.if:
389; CHECK-NEXT:     REPLICATE ir<%rem> = srem vp<[[SPLICE]]>, ir<%x>
390; CHECK-NEXT:   Successor(s): pred.srem.continue
391; CHECK-EMPTY:
392; CHECK-NEXT:   pred.srem.continue:
393; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%rem>
394; CHECK-NEXT:   No successors
395; CHECK-NEXT: }
396; CHECK-NEXT: Successor(s): loop.1.split
397; CHECK-EMPTY:
398; CHECK-NEXT: loop.1.split:
399; CHECK-NEXT: Successor(s): pred.store
400; CHECK-EMPTY:
401; CHECK-NEXT: <xVFxUF> pred.store: {
402; CHECK-NEXT:   pred.store.entry:
403; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
404; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
405; CHECK-NEXT:   CondBit: vp<[[MASK]]> (vector.body)
406; CHECK-EMPTY:
407; CHECK-NEXT:   pred.store.if:
408; CHECK-NEXT:     REPLICATE ir<%rem.div> = sdiv ir<20>, vp<[[PRED]]>
409; CHECK-NEXT:     REPLICATE ir<%gep> = getelementptr ir<%ptr>, vp<[[STEPS]]>
410; CHECK-NEXT:     REPLICATE store ir<%rem.div>, ir<%gep>
411; CHECK-NEXT:   Successor(s): pred.store.continue
412; CHECK-EMPTY:
413; CHECK-NEXT:   pred.store.continue:
414; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED2:%.+]]> = ir<%rem.div>
415; CHECK-NEXT:   No successors
416; CHECK-NEXT: }
417; CHECK-NEXT: Successor(s): loop.2
418; CHECK-EMPTY:
419; CHECK-NEXT: loop.2:
420; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = VF * UF + vp<[[CAN_IV]]>
421; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]> vp<[[VEC_TC]]>
422; CHECK-NEXT: No successors
423; CHECK-NEXT: }
424; CHECK-NEXT: Successor(s): middle.block
425; CHECK-EMPTY:
426; CHECK-NEXT: middle.block:
427; CHECK-NEXT: No successors
428; CHECK-NEXT: }
429;
430entry:
431  br label %loop
432
433loop:                                             ; preds = %loop, %entry
434  %recur = phi i32 [ 0, %entry ], [ %recur.next, %loop ]
435  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
436  %rem = srem i32 %recur, %x
437  %rem.div = sdiv i32 20, %rem
438  %recur.next = sext i8 %y to i32
439  %gep = getelementptr i32, i32* %ptr, i32 %iv
440  store i32 %rem.div, i32* %gep
441  %iv.next = add nsw i32 %iv, 1
442  %C = icmp sgt i32 %iv.next, %recur.next
443  br i1 %C, label %exit, label %loop
444
445exit:                                             ; preds = %loop
446  ret void
447}
448