[RISCV] Reduce redundancy in vnsrl tests
[llvm-project.git] / llvm / test / Transforms / LoopVectorize / vplan-sink-scalars-and-merge.ll
blob8872ad4e3897dedcecfa92bab0a1bd4db3a84eaa
1 ; REQUIRES: asserts
3 ; RUN: opt -passes=loop-vectorize -force-vector-interleave=1 -force-vector-width=2 -debug -disable-output %s 2>&1 | FileCheck %s
5 target 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"
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
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: No successors
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:   WIDEN-INDUCTION %iv = phi 0, %iv.next, ir<1>, vp<[[VF]]>
31 ; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
32 ; CHECK-NEXT: Successor(s): pred.store
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
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
49 ; CHECK:      pred.store.continue:
50 ; CHECK-NEXT:   No successors
51 ; CHECK-NEXT: }
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: }
59 define void @sink1(i32 %k) {
60 entry:
61   br label %loop
63 loop:
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
77 exit:
78   ret void
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: No successors
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:   WIDEN-INDUCTION %iv = phi 0, %iv.next, ir<1>, vp<[[VF]]
100 ; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
101 ; CHECK-NEXT: Successor(s): pred.load
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
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
114 ; CHECK:      pred.load.continue:
115 ; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv.b>
116 ; CHECK-NEXT:   No successors
117 ; CHECK-NEXT: }
119 ; CHECK:      loop.0:
120 ; CHECK-NEXT:   WIDEN ir<%mul> = mul ir<%iv>, ir<2>
121 ; CHECK-NEXT: Successor(s): pred.store
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
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
134 ; CHECK:      pred.store.continue:
135 ; CHECK-NEXT:   No successors
136 ; CHECK-NEXT: }
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: }
144 define void @sink2(i32 %k) {
145 entry:
146   br label %loop
148 loop:
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
162 exit:
163   ret void
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: No successors
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:   WIDEN-INDUCTION %iv = phi 0, %iv.next, ir<1>, vp<[[VF]]
185 ; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
186 ; CHECK-NEXT: Successor(s): pred.load
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
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
199 ; CHECK:       pred.load.continue:
200 ; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv.b>
201 ; CHECK-NEXT:   No successors
202 ; CHECK-NEXT: }
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
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
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
219 ; CHECK:      pred.store.continue:
220 ; CHECK-NEXT:   No successors
221 ; CHECK-NEXT: }
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: }
229 define void @sink3(i32 %k) {
230 entry:
231   br label %loop
233 loop:
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
247 exit:
248   ret void
251 ; Make sure we do not sink uniform instructions.
252 define 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: vector.ph:
262 ; CHECK-NEXT:   CLONE ir<%gep.A.uniform> = getelementptr inbounds ir<%A>, ir<0>
263 ; CHECK-NEXT: Successor(s): vector loop
264 ; CHECK-EMPTY:
265 ; CHECK-NEXT: <x1> vector loop: {
266 ; CHECK-NEXT: vector.body:
267 ; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
268 ; CHECK-NEXT:   WIDEN-INDUCTION %iv = phi 21, %iv.next, ir<1>, vp<[[VF]]>
269 ; CHECK-NEXT:   vp<[[DERIVED_IV:%.+]]> = DERIVED-IV ir<21> + vp<[[CAN_IV]]> * ir<1>
270 ; CHECK-NEXT:   EMIT vp<[[WIDE_CAN_IV:%.+]]> = WIDEN-CANONICAL-INDUCTION vp<[[CAN_IV]]>
271 ; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule vp<[[WIDE_CAN_IV]]>, vp<[[BTC]]>
272 ; CHECK-NEXT:   CLONE ir<%lv> = load ir<%gep.A.uniform>
273 ; CHECK-NEXT:   WIDEN ir<%cmp> = icmp ult ir<%iv>, ir<%k>
274 ; CHECK-NEXT:   EMIT vp<[[NOT2:%.+]]> = not ir<%cmp>
275 ; CHECK-NEXT:   EMIT vp<[[MASK2:%.+]]> = logical-and vp<[[MASK]]>, vp<[[NOT2]]>
276 ; CHECK-NEXT: Successor(s): pred.store
277 ; CHECK-EMPTY:
278 ; CHECK-NEXT: <xVFxUF> pred.store: {
279 ; CHECK-NEXT:   pred.store.entry:
280 ; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK2]]>
281 ; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
282 ; CHECK-EMPTY:
283 ; CHECK-NEXT:   pred.store.if:
284 ; CHECK-NEXT:     vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[DERIVED_IV]]>, ir<1>
285 ; CHECK-NEXT:     REPLICATE ir<%gep.B> = getelementptr inbounds ir<%B>, vp<[[STEPS]]>
286 ; CHECK-NEXT:     REPLICATE store ir<%lv>, ir<%gep.B>
287 ; CHECK-NEXT:   Successor(s): pred.store.continue
288 ; CHECK-EMPTY:
289 ; CHECK-NEXT:   pred.store.continue:
290 ; CHECK-NEXT:   No successors
291 ; CHECK-NEXT: }
292 ; CHECK-NEXT: Successor(s): loop.then.0
293 ; CHECK-EMPTY:
294 ; CHECK-NEXT: loop.then.0:
295 ; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
296 ; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
297 ; CHECK-NEXT: No successors
298 ; CHECK-NEXT: }
300 entry:
301   br label %loop
303 loop:
304   %iv = phi i64 [ 21, %entry ], [ %iv.next, %loop.latch ]
305   %gep.A.uniform = getelementptr inbounds i16, ptr %A, i64 0
306   %gep.B = getelementptr inbounds i16, ptr %B, i64 %iv
307   %lv = load i16, ptr %gep.A.uniform, align 1
308   %cmp = icmp ult i64 %iv, %k
309   br i1 %cmp, label %loop.latch, label %loop.then
311 loop.then:
312   store i16 %lv, ptr %gep.B, align 1
313   br label %loop.latch
315 loop.latch:
316   %iv.next = add nsw i64 %iv, 1
317   %cmp179 = icmp slt i64 %iv.next, 32
318   br i1 %cmp179, label %loop, label %exit
319 exit:
320   ret void
323 ; Loop with predicated load.
324 define void @pred_cfg1(i32 %k, i32 %j) {
325 ; CHECK-LABEL: LV: Checking a loop in 'pred_cfg1'
326 ; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
327 ; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
328 ; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
329 ; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
330 ; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
331 ; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count
332 ; CHECK-EMPTY:
333 ; CHECK-NEXT: ir-bb<entry>:
334 ; CHECK-NEXT:   EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw>
335 ; CHECK-NEXT: No successors
336 ; CHECK-EMPTY:
337 ; CHECK-NEXT: vector.ph:
338 ; CHECK-NEXT: Successor(s): vector loop
339 ; CHECK-EMPTY:
340 ; CHECK-NEXT: <x1> vector loop: {
341 ; CHECK-NEXT: vector.body:
342 ; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
343 ; CHECK-NEXT:   WIDEN-INDUCTION %iv = phi 0, %iv.next, ir<1>, vp<[[VF]]>
344 ; CHECK-NEXT:   EMIT vp<[[MASK1:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
345 ; CHECK-NEXT:   WIDEN ir<%c.1> = icmp ult ir<%iv>, ir<%j>
346 ; CHECK-NEXT:   WIDEN ir<%mul> = mul ir<%iv>, ir<10>
347 ; CHECK-NEXT:   EMIT vp<[[MASK2:%.+]]> = logical-and vp<[[MASK1]]>, ir<%c.1>
348 ; CHECK-NEXT: Successor(s): pred.load
349 ; CHECK-EMPTY:
350 ; CHECK-NEXT: <xVFxUF> pred.load: {
351 ; CHECK-NEXT:   pred.load.entry:
352 ; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK2]]>
353 ; CHECK-NEXT:   Successor(s): pred.load.if, pred.load.continue
354 ; CHECK-EMPTY:
355 ; CHECK-NEXT:   pred.load.if:
356 ; CHECK-NEXT:     vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
357 ; CHECK-NEXT:     REPLICATE ir<%gep.b> = getelementptr inbounds ir<@b>, ir<0>, vp<[[STEPS]]>
358 ; CHECK-NEXT:     REPLICATE ir<%lv.b> = load ir<%gep.b> (S->V)
359 ; CHECK-NEXT:   Successor(s): pred.load.continue
360 ; CHECK-EMPTY:
361 ; CHECK-NEXT:   pred.load.continue:
362 ; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv.b>
363 ; CHECK-NEXT:   No successors
364 ; CHECK-NEXT: }
365 ; CHECK-NEXT: Successor(s): then.0.0
366 ; CHECK-EMPTY:
367 ; CHECK-NEXT: then.0.0:
368 ; CHECK-NEXT:   BLEND ir<%p> = ir<0> vp<[[PRED]]>/vp<[[MASK2]]>
369 ; CHECK-NEXT: Successor(s): pred.store
370 ; CHECK-EMPTY:
371 ; CHECK-NEXT: <xVFxUF> pred.store: {
372 ; CHECK-NEXT:   pred.store.entry:
373 ; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK1]]>
374 ; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
375 ; CHECK-EMPTY:
376 ; CHECK-NEXT:   pred.store.if:
377 ; CHECK-NEXT:     REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, ir<%mul>
378 ; CHECK-NEXT:     REPLICATE store ir<%p>, ir<%gep.a>
379 ; CHECK-NEXT:   Successor(s): pred.store.continue
380 ; CHECK-EMPTY:
381 ; CHECK-NEXT:   pred.store.continue:
382 ; CHECK-NEXT:   No successors
383 ; CHECK-NEXT: }
384 ; CHECK-NEXT: Successor(s): next.0.1
385 ; CHECK-EMPTY:
386 ; CHECK-NEXT: next.0.1:
387 ; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
388 ; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
389 ; CHECK-NEXT: No successors
390 ; CHECK-NEXT: }
392 entry:
393   br label %loop
395 loop:
396   %iv = phi i32 [ 0, %entry ], [ %iv.next, %next.0 ]
397   %gep.b = getelementptr inbounds [2048 x i32], ptr @b, i32 0, i32 %iv
398   %c.1 = icmp ult i32 %iv, %j
399   %mul = mul i32 %iv, 10
400   %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %mul
401   br i1 %c.1, label %then.0, label %next.0
403 then.0:
404   %lv.b  = load i32, ptr %gep.b, align 4
405   br label %next.0
407 next.0:
408   %p = phi i32 [ 0, %loop ], [ %lv.b, %then.0 ]
409   store i32 %p, ptr %gep.a, align 4
410   %iv.next = add i32 %iv, 1
411   %large = icmp sge i32 %iv, 8
412   %exitcond = icmp eq i32 %iv, %k
413   %realexit = or i1 %large, %exitcond
414   br i1 %realexit, label %exit, label %loop
416 exit:
417   ret void
420 ; Loop with predicated load and store in separate blocks, store depends on
421 ; loaded value.
422 define void @pred_cfg2(i32 %k, i32 %j) {
423 ; CHECK-LABEL: LV: Checking a loop in 'pred_cfg2'
424 ; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
425 ; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
426 ; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
427 ; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
428 ; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
429 ; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count
430 ; CHECK-EMPTY:
431 ; CHECK-NEXT: ir-bb<entry>:
432 ; CHECK-NEXT:   EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw>
433 ; CHECK-NEXT: No successors
434 ; CHECK-EMPTY:
435 ; CHECK-NEXT: vector.ph:
436 ; CHECK-NEXT: Successor(s): vector loop
437 ; CHECK-EMPTY:
438 ; CHECK-NEXT: <x1> vector loop: {
439 ; CHECK-NEXT: vector.body:
440 ; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
441 ; CHECK-NEXT:   WIDEN-INDUCTION %iv = phi 0, %iv.next, ir<1>, vp<[[VF]]>
442 ; CHECK-NEXT:   EMIT vp<[[MASK1:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
443 ; CHECK-NEXT:   WIDEN ir<%mul> = mul ir<%iv>, ir<10>
444 ; CHECK-NEXT:   WIDEN ir<%c.0> = icmp ult ir<%iv>, ir<%j>
445 ; CHECK-NEXT:   WIDEN ir<%c.1> = icmp ugt ir<%iv>, ir<%j>
446 ; CHECK-NEXT:   EMIT vp<[[MASK2:%.+]]> = logical-and vp<[[MASK1]]>, ir<%c.0>
447 ; CHECK-NEXT: Successor(s): pred.load
448 ; CHECK-EMPTY:
449 ; CHECK-NEXT: <xVFxUF> pred.load: {
450 ; CHECK-NEXT:   pred.load.entry:
451 ; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK2]]>
452 ; CHECK-NEXT:   Successor(s): pred.load.if, pred.load.continue
453 ; CHECK-EMPTY:
454 ; CHECK-NEXT:   pred.load.if:
455 ; CHECK-NEXT:     vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
456 ; CHECK-NEXT:     REPLICATE ir<%gep.b> = getelementptr inbounds ir<@b>, ir<0>, vp<[[STEPS]]>
457 ; CHECK-NEXT:     REPLICATE ir<%lv.b> = load ir<%gep.b> (S->V)
458 ; CHECK-NEXT:   Successor(s): pred.load.continue
459 ; CHECK-EMPTY:
460 ; CHECK-NEXT:   pred.load.continue:
461 ; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv.b>
462 ; CHECK-NEXT:   No successors
463 ; CHECK-NEXT: }
464 ; CHECK-NEXT: Successor(s): then.0.0
465 ; CHECK-EMPTY:
466 ; CHECK-NEXT: then.0.0:
467 ; CHECK-NEXT:   BLEND ir<%p> = ir<0> vp<[[PRED]]>/vp<[[MASK2]]>
468 ; CHECK-NEXT:   EMIT vp<[[MASK3:%.+]]> = logical-and vp<[[MASK1]]>, ir<%c.1>
469 ; CHECK-NEXT: Successor(s): pred.store
470 ; CHECK-EMPTY:
471 ; CHECK-NEXT: <xVFxUF> pred.store: {
472 ; CHECK-NEXT:   pred.store.entry:
473 ; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK3]]>
474 ; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
475 ; CHECK-EMPTY:
476 ; CHECK-NEXT:   pred.store.if:
477 ; CHECK-NEXT:     REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, ir<%mul>
478 ; CHECK-NEXT:     REPLICATE store ir<%p>, ir<%gep.a>
479 ; CHECK-NEXT:   Successor(s): pred.store.continue
480 ; CHECK-EMPTY:
481 ; CHECK-NEXT:   pred.store.continue:
482 ; CHECK-NEXT:   No successors
483 ; CHECK-NEXT: }
484 ; CHECK-NEXT: Successor(s): then.1.1
485 ; CHECK-EMPTY:
486 ; CHECK-NEXT: then.1.1:
487 ; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
488 ; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
489 ; CHECK-NEXT: No successors
490 ; CHECK-NEXT: }
492 entry:
493   br label %loop
495 loop:
496   %iv = phi i32 [ 0, %entry ], [ %iv.next, %next.1 ]
497   %gep.b = getelementptr inbounds [2048 x i32], ptr @b, i32 0, i32 %iv
498   %mul = mul i32 %iv, 10
499   %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %mul
500   %c.0 = icmp ult i32 %iv, %j
501   %c.1 = icmp ugt i32 %iv, %j
502   br i1 %c.0, label %then.0, label %next.0
504 then.0:
505   %lv.b  = load i32, ptr %gep.b, align 4
506   br label %next.0
508 next.0:
509   %p = phi i32 [ 0, %loop ], [ %lv.b, %then.0 ]
510   br i1 %c.1, label %then.1, label %next.1
512 then.1:
513   store i32 %p, ptr %gep.a, align 4
514   br label %next.1
516 next.1:
517   %iv.next = add i32 %iv, 1
518   %large = icmp sge i32 %iv, 8
519   %exitcond = icmp eq i32 %iv, %k
520   %realexit = or i1 %large, %exitcond
521   br i1 %realexit, label %exit, label %loop
523 exit:
524   ret void
527 ; Loop with predicated load and store in separate blocks, store does not depend
528 ; on loaded value.
529 define void @pred_cfg3(i32 %k, i32 %j) {
530 ; CHECK-LABEL: LV: Checking a loop in 'pred_cfg3'
531 ; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
532 ; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
533 ; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
534 ; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
535 ; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
536 ; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count
537 ; CHECK-EMPTY:
538 ; CHECK-NEXT: ir-bb<entry>:
539 ; CHECK-NEXT:   EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw>
540 ; CHECK-NEXT: No successors
541 ; CHECK-EMPTY:
542 ; CHECK-NEXT: vector.ph:
543 ; CHECK-NEXT: Successor(s): vector loop
544 ; CHECK-EMPTY:
545 ; CHECK-NEXT: <x1> vector loop: {
546 ; CHECK-NEXT: vector.body:
547 ; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
548 ; CHECK-NEXT:   WIDEN-INDUCTION %iv = phi 0, %iv.next, ir<1>, vp<[[VF]]>
549 ; CHECK-NEXT:   EMIT vp<[[MASK1:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
550 ; CHECK-NEXT:   WIDEN ir<%mul> = mul ir<%iv>, ir<10>
551 ; CHECK-NEXT:   WIDEN ir<%c.0> = icmp ult ir<%iv>, ir<%j>
552 ; CHECK-NEXT:   EMIT vp<[[MASK2:%.+]]> = logical-and vp<[[MASK1:%.+]]>, ir<%c.0>
553 ; CHECK-NEXT: Successor(s): pred.load
554 ; CHECK-EMPTY:
555 ; CHECK-NEXT: <xVFxUF> pred.load: {
556 ; CHECK-NEXT:   pred.load.entry:
557 ; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK2]]>
558 ; CHECK-NEXT:   Successor(s): pred.load.if, pred.load.continue
559 ; CHECK-EMPTY:
560 ; CHECK-NEXT:   pred.load.if:
561 ; CHECK-NEXT:     vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
562 ; CHECK-NEXT:     REPLICATE ir<%gep.b> = getelementptr inbounds ir<@b>, ir<0>, vp<[[STEPS]]>
563 ; CHECK-NEXT:     REPLICATE ir<%lv.b> = load ir<%gep.b>
564 ; CHECK-NEXT:   Successor(s): pred.load.continue
565 ; CHECK-EMPTY:
566 ; CHECK-NEXT:   pred.load.continue:
567 ; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv.b>
568 ; CHECK-NEXT:   No successors
569 ; CHECK-NEXT: }
570 ; CHECK-NEXT: Successor(s): then.0.0
571 ; CHECK-EMPTY:
572 ; CHECK-NEXT: then.0.0:
573 ; CHECK-NEXT:   BLEND ir<%p> = ir<0> vp<[[PRED]]>/vp<[[MASK2]]>
574 ; CHECK-NEXT:   EMIT vp<[[MASK3:%.+]]> = logical-and vp<[[MASK1]]>, ir<%c.0>
575 ; CHECK-NEXT: Successor(s): pred.store
576 ; CHECK-EMPTY:
577 ; CHECK-NEXT: <xVFxUF> pred.store: {
578 ; CHECK-NEXT:   pred.store.entry:
579 ; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK3]]>
580 ; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
581 ; CHECK-EMPTY:
582 ; CHECK-NEXT:   pred.store.if:
583 ; CHECK-NEXT:     REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, ir<%mul>
584 ; CHECK-NEXT:     REPLICATE store ir<0>, ir<%gep.a>
585 ; CHECK-NEXT:     REPLICATE ir<%gep.c> = getelementptr inbounds ir<@c>, ir<0>, ir<%mul>
586 ; CHECK-NEXT:     REPLICATE store ir<%p>, ir<%gep.c>
587 ; CHECK-NEXT:   Successor(s): pred.store.continue
588 ; CHECK-EMPTY:
589 ; CHECK-NEXT:   pred.store.continue:
590 ; CHECK-NEXT:   No successors
591 ; CHECK-NEXT: }
592 ; CHECK-NEXT: Successor(s): then.1.2
593 ; CHECK-EMPTY:
594 ; CHECK-NEXT: then.1.2:
595 ; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
596 ; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
597 ; CHECK-NEXT: No successors
598 ; CHECK-NEXT: }
600 entry:
601   br label %loop
603 loop:
604   %iv = phi i32 [ 0, %entry ], [ %iv.next, %next.1 ]
605   %gep.b = getelementptr inbounds [2048 x i32], ptr @b, i32 0, i32 %iv
606   %mul = mul i32 %iv, 10
607   %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %mul
608   %gep.c = getelementptr inbounds [2048 x i32], ptr @c, i32 0, i32 %mul
609   %c.0 = icmp ult i32 %iv, %j
610   br i1 %c.0, label %then.0, label %next.0
612 then.0:
613   %lv.b  = load i32, ptr %gep.b, align 4
614   br label %next.0
616 next.0:
617   %p = phi i32 [ 0, %loop ], [ %lv.b, %then.0 ]
618   br i1 %c.0, label %then.1, label %next.1
620 then.1:
621   store i32 0, ptr %gep.a, align 4
622   store i32 %p, ptr %gep.c, align 4
623   br label %next.1
625 next.1:
626   %iv.next = add i32 %iv, 1
627   %large = icmp sge i32 %iv, 8
628   %exitcond = icmp eq i32 %iv, %k
629   %realexit = or i1 %large, %exitcond
630   br i1 %realexit, label %exit, label %loop
632 exit:
633   ret void
636 define void @merge_3_replicate_region(i32 %k, i32 %j) {
637 ; CHECK-LABEL: LV: Checking a loop in 'merge_3_replicate_region'
638 ; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
639 ; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
640 ; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
641 ; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
642 ; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
643 ; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count
644 ; CHECK-EMPTY:
645 ; CHECK-NEXT: ir-bb<entry>:
646 ; CHECK-NEXT:   EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw>
647 ; CHECK-NEXT: No successors
648 ; CHECK-EMPTY:
649 ; CHECK-NEXT: vector.ph:
650 ; CHECK-NEXT: Successor(s): vector loop
651 ; CHECK-EMPTY:
652 ; CHECK-NEXT: <x1> vector loop: {
653 ; CHECK-NEXT: vector.body:
654 ; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
655 ; CHECK-NEXT:   WIDEN-INDUCTION %iv = phi 0, %iv.next, ir<1>, vp<[[VF]]>
656 ; CHECK-NEXT:   vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
657 ; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
658 ; CHECK-NEXT: Successor(s): pred.store
659 ; CHECK-EMPTY:
660 ; CHECK-NEXT: <xVFxUF> pred.store: {
661 ; CHECK-NEXT:   pred.store.entry:
662 ; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
663 ; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
664 ; CHECK-EMPTY:
665 ; CHECK-NEXT:   pred.store.if:
666 ; CHECK-NEXT:     REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, vp<[[STEPS]]>
667 ; CHECK-NEXT:     REPLICATE ir<%lv.a> = load ir<%gep.a>
668 ; CHECK-NEXT:     REPLICATE ir<%gep.b> = getelementptr inbounds ir<@b>, ir<0>, vp<[[STEPS]]>
669 ; CHECK-NEXT:     REPLICATE ir<%lv.b> = load ir<%gep.b>
670 ; CHECK-NEXT:     REPLICATE ir<%gep.c> = getelementptr inbounds ir<@c>, ir<0>, vp<[[STEPS]]>
671 ; CHECK-NEXT:     REPLICATE store ir<%lv.a>, ir<%gep.c>
672 ; CHECK-NEXT:     REPLICATE store ir<%lv.b>, ir<%gep.a>
673 ; CHECK-NEXT:   Successor(s): pred.store.continue
674 ; CHECK-EMPTY:
675 ; CHECK-NEXT:   pred.store.continue:
676 ; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED1:%.+]]> = ir<%lv.a>
677 ; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED2:%.+]]> = ir<%lv.b>
678 ; CHECK-NEXT:   No successors
679 ; CHECK-NEXT: }
680 ; CHECK-NEXT: Successor(s): loop.3
681 ; CHECK-EMPTY:
682 ; CHECK-NEXT: loop.3:
683 ; CHECK-NEXT:   WIDEN ir<%c.0> = icmp ult ir<%iv>, ir<%j>
684 ; CHECK-NEXT:   EMIT vp<[[MASK2:%.+]]> = logical-and vp<[[MASK]]>, ir<%c.0>
685 ; CHECK-NEXT:   WIDEN ir<%mul> = mul vp<[[PRED1]]>, vp<[[PRED2]]>
686 ; CHECK-NEXT: Successor(s): pred.store
687 ; CHECK-EMPTY:
688 ; CHECK-NEXT: <xVFxUF> pred.store: {
689 ; CHECK-NEXT:   pred.store.entry:
690 ; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK2]]>
691 ; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
692 ; CHECK-EMPTY:
693 ; CHECK-NEXT:   pred.store.if:
694 ; CHECK-NEXT:     REPLICATE ir<%gep.c.1> = getelementptr inbounds ir<@c>, ir<0>, vp<[[STEPS]]>
695 ; CHECK-NEXT:     REPLICATE store ir<%mul>, ir<%gep.c.1>
696 ; CHECK-NEXT:   Successor(s): pred.store.continue
697 ; CHECK-EMPTY:
698 ; CHECK-NEXT:   pred.store.continue:
699 ; CHECK-NEXT:   No successors
700 ; CHECK-NEXT: }
701 ; CHECK-NEXT: Successor(s): then.0.4
702 ; CHECK-EMPTY:
703 ; CHECK-NEXT: then.0.4:
704 ; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
705 ; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
706 ; CHECK-NEXT: No successors
707 ; CHECK-NEXT: }
709 entry:
710   br label %loop
712 loop:
713   %iv = phi i32 [ 0, %entry ], [ %iv.next, %latch ]
714   %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %iv
715   %lv.a  = load i32, ptr %gep.a, align 4
716   %gep.b = getelementptr inbounds [2048 x i32], ptr @b, i32 0, i32 %iv
717   %lv.b  = load i32, ptr %gep.b, align 4
718   %gep.c = getelementptr inbounds [2048 x i32], ptr @c, i32 0, i32 %iv
719   store i32 %lv.a, ptr %gep.c, align 4
720   store i32 %lv.b, ptr %gep.a, align 4
721   %c.0 = icmp ult i32 %iv, %j
722   br i1 %c.0, label %then.0, label %latch
724 then.0:
725   %mul = mul i32 %lv.a, %lv.b
726   %gep.c.1 = getelementptr inbounds [2048 x i32], ptr @c, i32 0, i32 %iv
727   store i32 %mul, ptr %gep.c.1, align 4
728   br label %latch
730 latch:
731   %iv.next = add i32 %iv, 1
732   %large = icmp sge i32 %iv, 8
733   %exitcond = icmp eq i32 %iv, %k
734   %realexit = or i1 %large, %exitcond
735   br i1 %realexit, label %exit, label %loop
737 exit:
738   ret void
742 define void @update_2_uses_in_same_recipe_in_merged_block(i32 %k) {
743 ; CHECK-LABEL: LV: Checking a loop in 'update_2_uses_in_same_recipe_in_merged_block'
744 ; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
745 ; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
746 ; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
747 ; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
748 ; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
749 ; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count
750 ; CHECK-EMPTY:
751 ; CHECK-NEXT: ir-bb<entry>:
752 ; CHECK-NEXT:   EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw>
753 ; CHECK-NEXT: No successors
754 ; CHECK-EMPTY:
755 ; CHECK-NEXT: vector.ph:
756 ; CHECK-NEXT: Successor(s): vector loop
757 ; CHECK-EMPTY:
758 ; CHECK-NEXT: <x1> vector loop: {
759 ; CHECK-NEXT: vector.body:
760 ; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
761 ; CHECK-NEXT:   WIDEN-INDUCTION %iv = phi 0, %iv.next, ir<1>, vp<[[VF]]>
762 ; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
763 ; CHECK-NEXT: Successor(s): pred.store
764 ; CHECK-EMPTY:
765 ; CHECK-NEXT: <xVFxUF> pred.store: {
766 ; CHECK-NEXT:   pred.store.entry:
767 ; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
768 ; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
769 ; CHECK-EMPTY:
770 ; CHECK-NEXT:   pred.store.if:
771 ; CHECK-NEXT:     vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
772 ; CHECK-NEXT:     REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, vp<[[STEPS]]>
773 ; CHECK-NEXT:     REPLICATE ir<%lv.a> = load ir<%gep.a>
774 ; CHECK-NEXT:     REPLICATE ir<%div> = sdiv ir<%lv.a>, ir<%lv.a>
775 ; CHECK-NEXT:     REPLICATE store ir<%div>, ir<%gep.a>
776 ; CHECK-NEXT:   Successor(s): pred.store.continue
777 ; CHECK-EMPTY:
778 ; CHECK-NEXT:   pred.store.continue:
779 ; CHECK-NEXT:   No successors
780 ; CHECK-NEXT: }
781 ; CHECK-NEXT: Successor(s): loop.2
782 ; CHECK-EMPTY:
783 ; CHECK-NEXT: loop.2:
784 ; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
785 ; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
786 ; CHECK-NEXT: No successors
787 ; CHECK-NEXT: }
789 entry:
790   br label %loop
792 loop:
793   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
794   %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %iv
795   %lv.a  = load i32, ptr %gep.a, align 4
796   %div = sdiv i32 %lv.a, %lv.a
797   store i32 %div, ptr %gep.a, align 4
798   %iv.next = add i32 %iv, 1
799   %large = icmp sge i32 %iv, 8
800   %exitcond = icmp eq i32 %iv, %k
801   %realexit = or i1 %large, %exitcond
802   br i1 %realexit, label %exit, label %loop
804 exit:
805   ret void
808 define void @recipe_in_merge_candidate_used_by_first_order_recurrence(i32 %k) {
809 ; CHECK-LABEL: LV: Checking a loop in 'recipe_in_merge_candidate_used_by_first_order_recurrence'
810 ; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
811 ; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
812 ; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
813 ; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
814 ; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
815 ; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count
816 ; CHECK-EMPTY:
817 ; CHECK-NEXT: ir-bb<entry>:
818 ; CHECK-NEXT:   EMIT vp<[[TC]]> = EXPAND SCEV (1 + (8 umin %k))<nuw><nsw>
819 ; CHECK-NEXT: No successors
820 ; CHECK-EMPTY:
821 ; CHECK-NEXT: vector.ph:
822 ; CHECK-NEXT: Successor(s): vector loop
823 ; CHECK-EMPTY:
824 ; CHECK-NEXT: <x1> vector loop: {
825 ; CHECK-NEXT: vector.body:
826 ; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
827 ; CHECK-NEXT:   WIDEN-INDUCTION %iv = phi 0, %iv.next, ir<1>, vp<[[VF]]>
828 ; CHECK-NEXT:   FIRST-ORDER-RECURRENCE-PHI ir<%for> = phi ir<0>, vp<[[PRED:%.+]]>
829 ; CHECK-NEXT:   vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
830 ; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = icmp ule ir<%iv>, vp<[[BTC]]>
831 ; CHECK-NEXT:   REPLICATE ir<%gep.a> = getelementptr inbounds ir<@a>, ir<0>, vp<[[STEPS]]>
832 ; CHECK-NEXT: Successor(s): pred.load
833 ; CHECK-EMPTY:
834 ; CHECK-NEXT: <xVFxUF> pred.load: {
835 ; CHECK-NEXT:   pred.load.entry:
836 ; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
837 ; CHECK-NEXT:   Successor(s): pred.load.if, pred.load.continue
838 ; CHECK-EMPTY:
839 ; CHECK-NEXT:   pred.load.if:
840 ; CHECK-NEXT:     REPLICATE ir<%lv.a> = load ir<%gep.a>
841 ; CHECK-NEXT:   Successor(s): pred.load.continue
842 ; CHECK-EMPTY:
843 ; CHECK-NEXT:   pred.load.continue:
844 ; CHECK-NEXT:     PHI-PREDICATED-INSTRUCTION vp<[[PRED]]> = ir<%lv.a>
845 ; CHECK-NEXT:   No successors
846 ; CHECK-NEXT: }
847 ; CHECK-NEXT: Successor(s): loop.0
848 ; CHECK-EMPTY:
849 ; CHECK-NEXT: loop.0:
850 ; CHECK-NEXT:   EMIT vp<[[SPLICE:%.+]]> = first-order splice ir<%for>, vp<[[PRED]]>
851 ; CHECK-NEXT: Successor(s): pred.store
852 ; CHECK-EMPTY:
853 ; CHECK-NEXT: <xVFxUF> pred.store: {
854 ; CHECK-NEXT:   pred.store.entry:
855 ; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
856 ; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
857 ; CHECK-EMPTY:
858 ; CHECK-NEXT:   pred.store.if:
859 ; CHECK-NEXT:     REPLICATE ir<%div> = sdiv vp<[[SPLICE]]>, vp<[[PRED]]>
860 ; CHECK-NEXT:     REPLICATE store ir<%div>, ir<%gep.a>
861 ; CHECK-NEXT:   Successor(s): pred.store.continue
862 ; CHECK-EMPTY:
863 ; CHECK-NEXT:   pred.store.continue:
864 ; CHECK-NEXT:   No successors
865 ; CHECK-NEXT: }
866 ; CHECK-NEXT: Successor(s): loop.2
867 ; CHECK-EMPTY:
868 ; CHECK-NEXT: loop.2:
869 ; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
870 ; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
871 ; CHECK-NEXT: No successors
872 ; CHECK-NEXT: }
874 entry:
875   br label %loop
877 loop:
878   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
879   %for = phi i32 [ 0, %entry ], [ %lv.a, %loop ]
880   %gep.a = getelementptr inbounds [2048 x i32], ptr @a, i32 0, i32 %iv
881   %lv.a  = load i32, ptr %gep.a, align 4
882   %div = sdiv i32 %for, %lv.a
883   store i32 %div, ptr %gep.a, align 4
884   %iv.next = add i32 %iv, 1
885   %large = icmp sge i32 %iv, 8
886   %exitcond = icmp eq i32 %iv, %k
887   %realexit = or i1 %large, %exitcond
888   br i1 %realexit, label %exit, label %loop
890 exit:
891   ret void
894 define void @update_multiple_users(ptr noalias %src, ptr noalias %dst, i1 %c) {
895 ; CHECK-LABEL: LV: Checking a loop in 'update_multiple_users'
896 ; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
897 ; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
898 ; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
899 ; CHECK-NEXT: Live-in ir<999> = original trip-count
900 ; CHECK-EMPTY:
901 ; CHECK-NEXT: vector.ph:
902 ; CHECK-NEXT: Successor(s): vector loop
903 ; CHECK-EMPTY:
904 ; CHECK-NEXT: <x1> vector loop: {
905 ; CHECK-NEXT: vector.body:
906 ; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
907 ; CHECK-NEXT: Successor(s): pred.store
908 ; CHECK-EMPTY:
909 ; CHECK-NEXT: <xVFxUF> pred.store: {
910 ; CHECK-NEXT:   pred.store.entry:
911 ; CHECK-NEXT:     BRANCH-ON-MASK ir<%c>
912 ; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
913 ; CHECK-EMPTY:
914 ; CHECK-NEXT:   pred.store.if:
915 ; CHECK-NEXT:     REPLICATE ir<%l1> = load ir<%src>
916 ; CHECK-NEXT:     REPLICATE ir<%l2> = trunc ir<%l1>
917 ; CHECK-NEXT:     REPLICATE ir<%cmp> = icmp eq ir<%l1>, ir<0>
918 ; CHECK-NEXT:     REPLICATE ir<%sel> = select ir<%cmp>, ir<5>, ir<%l2>
919 ; CHECK-NEXT:     REPLICATE store ir<%sel>, ir<%dst>
920 ; CHECK-NEXT:   Successor(s): pred.store.continue
921 ; CHECK-EMPTY:
922 ; CHECK-NEXT:   pred.store.continue:
923 ; CHECK-NEXT:   No successors
924 ; CHECK-NEXT: }
925 ; CHECK-NEXT: Successor(s): loop.then.1
926 ; CHECK-EMPTY:
927 ; CHECK-NEXT: loop.then.1:
928 ; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
929 ; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
930 ; CHECK-NEXT: No successors
931 ; CHECK-NEXT: }
933 entry:
934   br label %loop.header
936 loop.header:
937   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
938   br i1 %c, label %loop.then, label %loop.latch
940 loop.then:
941   %l1 = load i16, ptr %src, align 2
942   %l2 = trunc i16 %l1 to i8
943   %cmp = icmp eq i16 %l1, 0
944   %sel = select i1 %cmp, i8 5, i8 %l2
945   store i8 %sel, ptr %dst, align 1
946   %sext.l1 = sext i16 %l1 to i32
947   br label %loop.latch
949 loop.latch:
950   %iv.next = add nsw i64 %iv, 1
951   %ec = icmp eq i64 %iv.next, 999
952   br i1 %ec, label %exit, label %loop.header
954 exit:
955   ret void
958 define void @sinking_requires_duplication(ptr %addr) {
959 ; CHECK-LABEL: LV: Checking a loop in 'sinking_requires_duplication'
960 ; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
961 ; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
962 ; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
963 ; CHECK-NEXT: Live-in ir<201> = original trip-count
964 ; CHECK-EMPTY:
965 ; CHECK-NEXT: vector.ph:
966 ; CHECK-NEXT: Successor(s): vector loop
967 ; CHECK-EMPTY:
968 ; CHECK-NEXT: <x1> vector loop: {
969 ; CHECK-NEXT: vector.body:
970 ; CHECK-NEXT:   EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
971 ; CHECK-NEXT:   vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[CAN_IV]]>, ir<1>
972 ; CHECK-NEXT:   CLONE ir<%gep> = getelementptr ir<%addr>, vp<[[STEPS]]>
973 ; CHECK-NEXT:   vp<[[VEC_PTR:%.+]]> = vector-pointer ir<%gep>
974 ; CHECK-NEXT:   WIDEN ir<%0> = load vp<[[VEC_PTR]]>
975 ; CHECK-NEXT:   WIDEN ir<%pred> = fcmp oeq ir<%0>, ir<0.000000e+00>
976 ; CHECK-NEXT:   EMIT vp<[[MASK:%.+]]> = not ir<%pred>
977 ; CHECK-NEXT: Successor(s): pred.store
978 ; CHECK-EMPTY:
979 ; CHECK-NEXT: <xVFxUF> pred.store: {
980 ; CHECK-NEXT:   pred.store.entry:
981 ; CHECK-NEXT:     BRANCH-ON-MASK vp<[[MASK]]>
982 ; CHECK-NEXT:   Successor(s): pred.store.if, pred.store.continue
983 ; CHECK-EMPTY:
984 ; CHECK-NEXT:   pred.store.if:
985 ; CHECK-NEXT:     REPLICATE ir<%gep>.1 = getelementptr ir<%addr>, vp<[[STEPS]]>
986 ; CHECK-NEXT:     REPLICATE store ir<1.000000e+01>, ir<%gep>.1
987 ; CHECK-NEXT:   Successor(s): pred.store.continue
988 ; CHECK-EMPTY:
989 ; CHECK-NEXT:   pred.store.continue:
990 ; CHECK-NEXT:   No successors
991 ; CHECK-NEXT: }
992 ; CHECK-NEXT: Successor(s): then.0
993 ; CHECK-EMPTY:
994 ; CHECK-NEXT: then.0:
995 ; CHECK-NEXT:   EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
996 ; CHECK-NEXT:   EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
997 ; CHECK-NEXT: No successors
998 ; CHECK-NEXT: }
1000 entry:
1001   br label %loop.header
1003 loop.header:
1004   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
1005   %gep = getelementptr float, ptr %addr, i64 %iv
1006   %exitcond.not = icmp eq i64 %iv, 200
1007   br i1 %exitcond.not, label %exit, label %loop.body
1009 loop.body:
1010   %0 = load float, ptr %gep, align 4
1011   %pred = fcmp oeq float %0, 0.0
1012   br i1 %pred, label %loop.latch, label %then
1014 then:
1015   store float 10.0, ptr %gep, align 4
1016   br label %loop.latch
1018 loop.latch:
1019   %iv.next = add nuw nsw i64 %iv, 1
1020   br label %loop.header
1022 exit:
1023   ret void
1026 ; Test case with a dead GEP between the load and store regions. Dead recipes
1027 ; need to be removed before merging.
1028 define void @merge_with_dead_gep_between_regions(i32 %n, ptr noalias %src, ptr noalias %dst) optsize {
1029 ; CHECK-LABEL: LV: Checking a loop in 'merge_with_dead_gep_between_regions'
1030 ; CHECK:      VPlan 'Initial VPlan for VF={2},UF>=1' {
1031 ; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
1032 ; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
1033 ; CHECK-NEXT: Live-in vp<[[BTC:%.+]]> = backedge-taken count
1034 ; CHECK-NEXT: Live-in ir<%n> = original trip-count
1035 ; CHECK-EMPTY:
1036 ; CHECK-NEXT: vector.ph:
1037 ; CHECK-NEXT: Successor(s): vector loop
1038 ; CHECK-EMPTY:
1039 ; CHECK-NEXT: <x1> vector loop: {
1040 ; CHECK-NEXT:   vector.body:
1041 ; CHECK-NEXT:     EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
1042 ; CHECK-NEXT:     vp<[[DERIVED_IV:%.+]]> = DERIVED-IV ir<%n> + vp<[[CAN_IV]]> * ir<-1>
1043 ; CHECK-NEXT:     EMIT vp<[[WIDE_IV:%.+]]> = WIDEN-CANONICAL-INDUCTION vp<[[CAN_IV]]>
1044 ; CHECK-NEXT:     EMIT vp<[[MASK:%.+]]> = icmp ule vp<[[WIDE_IV]]>, vp<[[BTC]]>
1045 ; CHECK-NEXT:   Successor(s): pred.store
1046 ; CHECK-EMPTY:
1047 ; CHECK-NEXT:   <xVFxUF> pred.store: {
1048 ; CHECK-NEXT:     pred.store.entry:
1049 ; CHECK-NEXT:       BRANCH-ON-MASK vp<[[MASK]]>
1050 ; CHECK-NEXT:     Successor(s): pred.store.if, pred.store.continue
1051 ; CHECK-EMPTY:
1052 ; CHECK-NEXT:     pred.store.if:
1053 ; CHECK-NEXT:       vp<[[SCALAR_STEPS:%.+]]>    = SCALAR-STEPS vp<[[DERIVED_IV]]>, ir<-1>
1054 ; CHECK-NEXT:       REPLICATE ir<%gep.src> = getelementptr inbounds ir<%src>, vp<[[SCALAR_STEPS]]>
1055 ; CHECK-NEXT:       REPLICATE ir<%l> = load ir<%gep.src>
1056 ; CHECK-NEXT:       REPLICATE ir<%gep.dst> = getelementptr inbounds ir<%dst>, vp<[[SCALAR_STEPS]]>
1057 ; CHECK-NEXT:       REPLICATE store ir<%l>, ir<%gep.dst>
1058 ; CHECK-NEXT:     Successor(s): pred.store.continue
1059 ; CHECK-EMPTY:
1060 ; CHECK-NEXT:     pred.store.continue:
1061 ; CHECK-NEXT:     No successors
1062 ; CHECK-NEXT:   }
1063 ; CHECK-NEXT:   Successor(s): loop.1
1064 ; CHECK-EMPTY:
1065 ; CHECK-NEXT:   loop.1:
1066 ; CHECK-NEXT:     EMIT vp<[[CAN_IV_NEXT:%.+]]> = add vp<[[CAN_IV]]>, vp<[[VFxUF]]>
1067 ; CHECK-NEXT:     EMIT branch-on-count  vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
1068 ; CHECK-NEXT:   No successors
1069 ; CHECK-NEXT: }
1070 ; CHECK-NEXT: Successor(s): middle.block
1071 ; CHECK-EMPTY:
1072 ; CHECK-NEXT: middle.block:
1073 ; CHECK-NEXT:   EMIT branch-on-cond ir<true>
1074 ; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph
1075 ; CHECK-EMPTY:
1076 ; CHECK-NEXT: ir-bb<exit>
1077 ; CHECK-NEXT: No successors
1078 ; CHECK-EMPTY:
1079 ; CHECK-NEXT: scalar.ph
1080 ; CHECK-NEXT: Successor(s): ir-bb<loop>
1081 ; CHECK-EMPTY:
1082 ; CHECK-NEXT: ir-bb<loop>:
1083 ; CHECK-NEXT:   IR   %iv = phi i32 [ %n, %entry ], [ %iv.next, %loop ]
1084 ; CHECK-NEXT:   IR   %iv.next = add nsw i32 %iv, -1
1085 ; CHECK-NEXT:   IR   %gep.src = getelementptr inbounds i32, ptr %src, i32 %iv
1086 ; CHECK-NEXT:   IR   %l = load i32, ptr %gep.src, align 16
1087 ; CHECK-NEXT:   IR   %dead_gep = getelementptr inbounds i32, ptr %dst, i64 1
1088 ; CHECK-NEXT:   IR   %gep.dst = getelementptr inbounds i32, ptr %dst, i32 %iv
1089 ; CHECK-NEXT:   IR   store i32 %l, ptr %gep.dst, align 16
1090 ; CHECK-NEXT:   IR   %ec = icmp eq i32 %iv.next, 0
1091 ; CHECK-NEXT: No successors
1092 ; CHECK-NEXT: }
1094 entry:
1095   br label %loop
1097 loop:
1098   %iv = phi i32[ %n, %entry ], [ %iv.next, %loop ]
1099   %iv.next = add nsw i32 %iv, -1
1100   %gep.src = getelementptr inbounds i32, ptr %src, i32 %iv
1101   %l = load i32, ptr %gep.src, align 16
1102   %dead_gep = getelementptr inbounds i32, ptr %dst, i64 1
1103   %gep.dst = getelementptr inbounds i32, ptr %dst, i32 %iv
1104   store i32 %l, ptr %gep.dst, align 16
1105   %ec = icmp eq i32 %iv.next, 0
1106   br i1 %ec, label %exit, label %loop
1108 exit:
1109   ret void
1112 define void @ptr_induction_remove_dead_recipe(ptr %start, ptr %end) {
1113 ; CHECK-LABEL: LV: Checking a loop in 'ptr_induction_remove_dead_recipe'
1114 ; CHECK:       VPlan 'Initial VPlan for VF={2},UF>=1' {
1115 ; CHECK-NEXT: Live-in vp<[[VF:%.+]]> = VF
1116 ; CHECK-NEXT: Live-in vp<[[VFxUF:%.+]]> = VF * UF
1117 ; CHECK-NEXT: Live-in vp<[[VEC_TC:%.+]]> = vector-trip-count
1118 ; CHECK-NEXT: vp<[[TC:%.+]]> = original trip-count
1119 ; CHECK-EMPTY:
1120 ; CHECK-NEXT: ir-bb<entry>:
1121 ; CHECK-NEXT:  EMIT vp<[[TC]]> = EXPAND SCEV ((-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %start to i64))
1122 ; CHECK-NEXT: No successors
1123 ; CHECK-EMPTY:
1124 ; CHECK-NEXT: vector.ph:
1125 ; CHECK-NEXT: Successor(s): vector loop
1126 ; CHECK-EMPTY:
1127 ; CHECK-NEXT: <x1> vector loop: {
1128 ; CHECK-NEXT:   vector.body:
1129 ; CHECK-NEXT:     EMIT vp<[[CAN_IV:%.+]]> = CANONICAL-INDUCTION
1130 ; CHECK-NEXT:     vp<[[DEV_IV:%.+]]> = DERIVED-IV ir<0> + vp<[[CAN_IV]]> * ir<-1>
1131 ; CHECK-NEXT:     vp<[[STEPS:%.+]]> = SCALAR-STEPS vp<[[DEV_IV]]>, ir<-1>
1132 ; CHECK-NEXT:     EMIT vp<[[PTR_IV:%.+]]> = ptradd ir<%start>, vp<[[STEPS]]>
1133 ; CHECK-NEXT:     CLONE ir<%ptr.iv.next> = getelementptr inbounds vp<[[PTR_IV]]>, ir<-1>
1134 ; CHECK-NEXT:     vp<[[VEC_PTR:%.+]]> = reverse-vector-pointer inbounds ir<%ptr.iv.next>, vp<[[VF]]>
1135 ; CHECK-NEXT:     WIDEN ir<%l> = load vp<[[VEC_PTR]]>
1136 ; CHECK-NEXT:     WIDEN ir<%c.1> = icmp eq ir<%l>, ir<0>
1137 ; CHECK-NEXT:     EMIT vp<[[NEG:%.+]]> = not ir<%c.1>
1138 ; CHECK-NEXT:   Successor(s): pred.store
1139 ; CHECK-EMPTY:
1140 ; CHECK-NEXT:   <xVFxUF> pred.store: {
1141 ; CHECK-NEXT:     pred.store.entry:
1142 ; CHECK-NEXT:       BRANCH-ON-MASK vp<[[NEG]]>
1143 ; CHECK-NEXT:     Successor(s): pred.store.if, pred.store.continue
1144 ; CHECK-EMPTY:
1145 ; CHECK-NEXT:     pred.store.if:
1146 ; CHECK-NEXT:       REPLICATE ir<%ptr.iv.next>.1 = getelementptr inbounds vp<[[PTR_IV]]>, ir<-1>
1147 ; CHECK-NEXT:       REPLICATE store ir<95>, ir<%ptr.iv.next>.1
1148 ; CHECK-NEXT:     Successor(s): pred.store.continue
1149 ; CHECK-EMPTY:
1150 ; CHECK-NEXT:     pred.store.continue:
1151 ; CHECK-NEXT:     No successors
1152 ; CHECK-NEXT:   }
1153 ; CHECK-NEXT:   Successor(s): if.then.0
1154 ; CHECK-EMPTY:
1155 ; CHECK-NEXT:   if.then.0:
1156 ; CHECK-NEXT:     EMIT vp<[[CAN_IV_NEXT:%.+]]> = add nuw vp<[[CAN_IV]]>, vp<[[VFxUF]]>
1157 ; CHECK-NEXT:     EMIT branch-on-count vp<[[CAN_IV_NEXT]]>, vp<[[VEC_TC]]>
1158 ; CHECK-NEXT:   No successors
1159 ; CHECK-NEXT: }
1160 ; CHECK-NEXT: Successor(s): middle.block
1161 ; CHECK-EMPTY:
1162 ; CHECK-NEXT: middle.block:
1163 ; CHECK-NEXT:   EMIT vp<[[CMP:%.+]]> = icmp eq vp<[[TC]]>, vp<[[VEC_TC]]>
1164 ; CHECK-NEXT:   EMIT branch-on-cond vp<[[CMP]]>
1165 ; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph
1166 ; CHECK-EMPTY:
1167 ; CHECK-NEXT: ir-bb<exit>:
1168 ; CHECK-NEXT: No successors
1169 ; CHECK-EMPTY:
1170 ; CHECK-NEXT: scalar.ph:
1171 ; CHECK-NEXT: Successor(s): ir-bb<loop.header>
1172 ; CHECK-EMPTY:
1173 ; CHECK-NEXT: ir-bb<loop.header>:
1174 ; CHECK-NEXT:   IR   %ptr.iv = phi ptr [ %start, %entry ], [ %ptr.iv.next, %loop.latch ]
1175 ; CHECK-NEXT:   IR   %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 -1
1176 ; CHECK-NEXT:   IR   %l = load i8, ptr %ptr.iv.next, align 1
1177 ; CHECK-NEXT:   IR   %c.1 = icmp eq i8 %l, 0
1178 ; CHECK-NEXT: No successors
1179 ; CHECK-NEXT: }
1181 entry:
1182   br label %loop.header
1184 loop.header:
1185   %ptr.iv = phi ptr [ %start, %entry ], [ %ptr.iv.next, %loop.latch ]
1186   %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 -1
1187   %l = load i8, ptr %ptr.iv.next, align 1
1188   %c.1 = icmp eq i8 %l, 0
1189   br i1 %c.1, label %loop.latch, label %if.then
1191 if.then:
1192   store i8 95, ptr %ptr.iv.next, align 1
1193   br label %loop.latch
1195 loop.latch:
1196   %c.2 = icmp eq ptr %ptr.iv.next, %end
1197   br i1 %c.2, label %exit, label %loop.header
1199 exit:
1200   ret void