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
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
24 ; CHECK-NEXT: vector.ph:
25 ; CHECK-NEXT: Successor(s): vector loop
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
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
59 define void @sink1(i32 %k) {
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
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
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
93 ; CHECK-NEXT: vector.ph:
94 ; CHECK-NEXT: Successor(s): vector loop
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
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
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
144 define void @sink2(i32 %k) {
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
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
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
178 ; CHECK-NEXT: vector.ph:
179 ; CHECK-NEXT: Successor(s): vector loop
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
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
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
229 define void @sink3(i32 %k) {
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
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
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
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
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
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
289 ; CHECK-NEXT: pred.store.continue:
290 ; CHECK-NEXT: No successors
292 ; CHECK-NEXT: Successor(s): loop.then.0
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
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
312 store i16 %lv, ptr %gep.B, align 1
316 %iv.next = add nsw i64 %iv, 1
317 %cmp179 = icmp slt i64 %iv.next, 32
318 br i1 %cmp179, label %loop, label %exit
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
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
337 ; CHECK-NEXT: vector.ph:
338 ; CHECK-NEXT: Successor(s): vector loop
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
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
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
361 ; CHECK-NEXT: pred.load.continue:
362 ; CHECK-NEXT: PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv.b>
363 ; CHECK-NEXT: No successors
365 ; CHECK-NEXT: Successor(s): then.0.0
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
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
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
381 ; CHECK-NEXT: pred.store.continue:
382 ; CHECK-NEXT: No successors
384 ; CHECK-NEXT: Successor(s): next.0.1
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
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
404 %lv.b = load i32, ptr %gep.b, align 4
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
420 ; Loop with predicated load and store in separate blocks, store depends on
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
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
435 ; CHECK-NEXT: vector.ph:
436 ; CHECK-NEXT: Successor(s): vector loop
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
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
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
460 ; CHECK-NEXT: pred.load.continue:
461 ; CHECK-NEXT: PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv.b>
462 ; CHECK-NEXT: No successors
464 ; CHECK-NEXT: Successor(s): then.0.0
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
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
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
481 ; CHECK-NEXT: pred.store.continue:
482 ; CHECK-NEXT: No successors
484 ; CHECK-NEXT: Successor(s): then.1.1
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
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
505 %lv.b = load i32, ptr %gep.b, align 4
509 %p = phi i32 [ 0, %loop ], [ %lv.b, %then.0 ]
510 br i1 %c.1, label %then.1, label %next.1
513 store i32 %p, ptr %gep.a, align 4
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
527 ; Loop with predicated load and store in separate blocks, store does not depend
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
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
542 ; CHECK-NEXT: vector.ph:
543 ; CHECK-NEXT: Successor(s): vector loop
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
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
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
566 ; CHECK-NEXT: pred.load.continue:
567 ; CHECK-NEXT: PHI-PREDICATED-INSTRUCTION vp<[[PRED:%.+]]> = ir<%lv.b>
568 ; CHECK-NEXT: No successors
570 ; CHECK-NEXT: Successor(s): then.0.0
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
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
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
589 ; CHECK-NEXT: pred.store.continue:
590 ; CHECK-NEXT: No successors
592 ; CHECK-NEXT: Successor(s): then.1.2
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
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
613 %lv.b = load i32, ptr %gep.b, align 4
617 %p = phi i32 [ 0, %loop ], [ %lv.b, %then.0 ]
618 br i1 %c.0, label %then.1, label %next.1
621 store i32 0, ptr %gep.a, align 4
622 store i32 %p, ptr %gep.c, align 4
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
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
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
649 ; CHECK-NEXT: vector.ph:
650 ; CHECK-NEXT: Successor(s): vector loop
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
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
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
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
680 ; CHECK-NEXT: Successor(s): loop.3
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
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
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
698 ; CHECK-NEXT: pred.store.continue:
699 ; CHECK-NEXT: No successors
701 ; CHECK-NEXT: Successor(s): then.0.4
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
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
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
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
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
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
755 ; CHECK-NEXT: vector.ph:
756 ; CHECK-NEXT: Successor(s): vector loop
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
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
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
778 ; CHECK-NEXT: pred.store.continue:
779 ; CHECK-NEXT: No successors
781 ; CHECK-NEXT: Successor(s): loop.2
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
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
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
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
821 ; CHECK-NEXT: vector.ph:
822 ; CHECK-NEXT: Successor(s): vector loop
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
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
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
843 ; CHECK-NEXT: pred.load.continue:
844 ; CHECK-NEXT: PHI-PREDICATED-INSTRUCTION vp<[[PRED]]> = ir<%lv.a>
845 ; CHECK-NEXT: No successors
847 ; CHECK-NEXT: Successor(s): loop.0
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
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
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
863 ; CHECK-NEXT: pred.store.continue:
864 ; CHECK-NEXT: No successors
866 ; CHECK-NEXT: Successor(s): loop.2
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
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
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
901 ; CHECK-NEXT: vector.ph:
902 ; CHECK-NEXT: Successor(s): vector loop
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
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
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
922 ; CHECK-NEXT: pred.store.continue:
923 ; CHECK-NEXT: No successors
925 ; CHECK-NEXT: Successor(s): loop.then.1
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
934 br label %loop.header
937 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
938 br i1 %c, label %loop.then, label %loop.latch
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
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
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
965 ; CHECK-NEXT: vector.ph:
966 ; CHECK-NEXT: Successor(s): vector loop
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
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
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
989 ; CHECK-NEXT: pred.store.continue:
990 ; CHECK-NEXT: No successors
992 ; CHECK-NEXT: Successor(s): then.0
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
1001 br label %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
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
1015 store float 10.0, ptr %gep, align 4
1016 br label %loop.latch
1019 %iv.next = add nuw nsw i64 %iv, 1
1020 br label %loop.header
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
1036 ; CHECK-NEXT: vector.ph:
1037 ; CHECK-NEXT: Successor(s): vector loop
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
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
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
1060 ; CHECK-NEXT: pred.store.continue:
1061 ; CHECK-NEXT: No successors
1063 ; CHECK-NEXT: Successor(s): loop.1
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
1070 ; CHECK-NEXT: Successor(s): middle.block
1072 ; CHECK-NEXT: middle.block:
1073 ; CHECK-NEXT: EMIT branch-on-cond ir<true>
1074 ; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph
1076 ; CHECK-NEXT: ir-bb<exit>
1077 ; CHECK-NEXT: No successors
1079 ; CHECK-NEXT: scalar.ph
1080 ; CHECK-NEXT: Successor(s): ir-bb<loop>
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
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
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
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
1124 ; CHECK-NEXT: vector.ph:
1125 ; CHECK-NEXT: Successor(s): vector loop
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
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
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
1150 ; CHECK-NEXT: pred.store.continue:
1151 ; CHECK-NEXT: No successors
1153 ; CHECK-NEXT: Successor(s): if.then.0
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
1160 ; CHECK-NEXT: Successor(s): middle.block
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
1167 ; CHECK-NEXT: ir-bb<exit>:
1168 ; CHECK-NEXT: No successors
1170 ; CHECK-NEXT: scalar.ph:
1171 ; CHECK-NEXT: Successor(s): ir-bb<loop.header>
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
1182 br label %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
1192 store i8 95, ptr %ptr.iv.next, align 1
1193 br label %loop.latch
1196 %c.2 = icmp eq ptr %ptr.iv.next, %end
1197 br i1 %c.2, label %exit, label %loop.header