[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / LoopUnswitch / partial-unswitch.ll
blob96a6b0f4e2b5f5eced852f97c183ed3066948bc1
1 ; RUN: opt -loop-unswitch -verify-dom-info -verify-memoryssa -S -enable-new-pm=0 %s | FileCheck %s
3 declare void @clobber()
5 define i32 @partial_unswitch_true_successor(i32* %ptr, i32 %N) {
6 ; CHECK-LABEL: @partial_unswitch_true_successor
7 ; CHECK-LABEL: entry:
8 ; CHECK-NEXT:   [[LV:%[0-9]+]] = load i32, i32* %ptr, align 4
9 ; CHECK-NEXT:   [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
10 ; CHECK-NEXT:   br i1 [[C]], label %[[SPLIT_TRUE_PH:[a-z._]+]], label %[[FALSE_CRIT:[a-z._]+]]
12 ; CHECK:      [[FALSE_CRIT]]:
13 ; CHECK-NEXT:   br label %[[FALSE_PH:[a-z.]+]]
15 ; CHECK:      [[SPLIT_TRUE_PH]]:
16 ; CHECK-NEXT:   br label %[[TRUE_HEADER:[a-z.]+]]
18 ; CHECK: [[TRUE_HEADER]]:
19 ; CHECK-NEXT:   phi i32
20 ; CHECK-NEXT:    [[TRUE_LV:%[a-z.0-9]+]] = load i32, i32* %ptr, align 4
21 ; CHECK-NEXT:    [[TRUE_C:%[a-z.0-9]+]] = icmp eq i32 [[TRUE_LV]], 100
22 ; CHECK-NEXT:    br i1 true, label %[[TRUE_NOCLOBBER:.+]], label %[[TRUE_CLOBBER:[a-z0-9._]+]]
24 ; CHECK: [[TRUE_CLOBBER]]:
25 ; CHECK-NEXT:  call
26 ; CHECK-NEXT:  br label %[[TRUE_LATCH:[a-z0-9._]+]]
28 ; CHECK: [[TRUE_NOCLOBBER]]:
29 ; CHECK-NEXT:  br label %[[TRUE_LATCH:[a-z0-9._]+]]
31 ; CHECK: [[TRUE_LATCH]]:
32 ; CHECK-NEXT:   icmp
33 ; CHECK-NEXT:   add
34 ; CHECK-NEXT:   br {{.*}} label %[[TRUE_HEADER]]
37 ; CHECK:      [[FALSE_PH]]:
38 ; CHECK-NEXT:   br label %[[FALSE_HEADER:[a-z.]+]]
40 ; CHECK: [[FALSE_HEADER]]:
41 ; CHECK-NEXT:   phi i32
42 ; CHECK-NEXT:    [[FALSE_LV:%[a-z.0-9]+]] = load i32, i32* %ptr, align 4
43 ; CHECK-NEXT:    [[FALSE_C:%[a-z.0-9]+]] = icmp eq i32 [[FALSE_LV]], 100
44 ; CHECK-NEXT:     br i1 [[FALSE_C]], label  %[[FALSE_NOCLOBBER:.+]], label %[[FALSE_CLOBBER:[a-z0-9._]+]]
46 ; CHECK: [[FALSE_NOCLOBBER]]:
47 ; CHECK-NEXT:  br label %[[FALSE_LATCH:[a-z0-9._]+]]
49 ; CHECK: [[FALSE_CLOBBER]]:
50 ; CHECK-NEXT:  call
51 ; CHECK-NEXT:  br label %[[FALSE_LATCH:[a-z0-9._]+]]
53 ; CHECK: [[FALSE_LATCH]]:
54 ; CHECK-NEXT:   icmp
55 ; CHECK-NEXT:   add
56 ; CHECK-NEXT:   br {{.*}} label %[[FALSE_HEADER]]
58 entry:
59   br label %loop.header
61 loop.header:
62   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
63   %lv = load i32, i32* %ptr
64   %sc = icmp eq i32 %lv, 100
65   br i1 %sc, label %noclobber, label %clobber
67 noclobber:
68   br label %loop.latch
70 clobber:
71   call void @clobber()
72   br label %loop.latch
74 loop.latch:
75   %c = icmp ult i32 %iv, %N
76   %iv.next = add i32 %iv, 1
77   br i1 %c, label %loop.header, label %exit
79 exit:
80   ret i32 10
83 define i32 @partial_unswitch_false_successor(i32* %ptr, i32 %N) {
84 ; CHECK-LABEL: @partial_unswitch_false_successor
85 ; CHECK-LABEL: entry:
86 ; CHECK-NEXT:   [[LV:%[0-9]+]] = load i32, i32* %ptr, align 4
87 ; CHECK-NEXT:   [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
88 ; CHECK-NEXT:   br i1 [[C]], label %[[SPLIT_TRUE_PH:[a-z._]+]], label %[[FALSE_CRIT:[a-z._]+]]
90 ; CHECK:      [[FALSE_CRIT]]:
91 ; CHECK-NEXT:   br label %[[FALSE_PH:[a-z.]+]]
93 ; CHECK:      [[SPLIT_TRUE_PH]]:
94 ; CHECK-NEXT:   br label %[[TRUE_HEADER:[a-z.]+]]
96 ; CHECK: [[TRUE_HEADER]]:
97 ; CHECK-NEXT:   phi i32
98 ; CHECK-NEXT:    [[TRUE_LV:%[a-z.0-9]+]] = load i32, i32* %ptr, align 4
99 ; CHECK-NEXT:    [[TRUE_C:%[a-z.0-9]+]] = icmp eq i32 [[TRUE_LV]], 100
100 ; CHECK-NEXT:    br i1 [[TRUE_C]], label %[[TRUE_CLOBBER:.+]], label %[[TRUE_NOCLOBBER:[a-z0-9._]+]]
102 ; CHECK: [[TRUE_NOCLOBBER]]:
103 ; CHECK-NEXT:  br label %[[TRUE_LATCH:[a-z0-9._]+]]
105 ; CHECK: [[TRUE_CLOBBER]]:
106 ; CHECK-NEXT:  call
107 ; CHECK-NEXT:  br label %[[TRUE_LATCH:[a-z0-9._]+]]
109 ; CHECK: [[TRUE_LATCH]]:
110 ; CHECK-NEXT:   icmp
111 ; CHECK-NEXT:   add
112 ; CHECK-NEXT:   br {{.*}} label %[[TRUE_HEADER]]
115 ; CHECK:      [[FALSE_PH]]:
116 ; CHECK-NEXT:   br label %[[FALSE_HEADER:[a-z.]+]]
118 ; CHECK: [[FALSE_HEADER]]:
119 ; CHECK-NEXT:   phi i32
120 ; CHECK-NEXT:    [[FALSE_LV:%[a-z.0-9]+]] = load i32, i32* %ptr, align 4
121 ; CHECK-NEXT:    [[FALSE_C:%[a-z.0-9]+]] = icmp eq i32 [[FALSE_LV]], 100
122 ; CHECK-NEXT:     br i1 false, label  %[[FALSE_CLOBBER:.+]], label %[[FALSE_NOCLOBBER:[a-z0-9._]+]]
124 ; CHECK: [[FALSE_CLOBBER]]:
125 ; CHECK-NEXT:  call
126 ; CHECK-NEXT:  br label %[[FALSE_LATCH:[a-z0-9._]+]]
128 ; CHECK: [[FALSE_NOCLOBBER]]:
129 ; CHECK-NEXT:  br label %[[FALSE_LATCH:[a-z0-9._]+]]
131 ; CHECK: [[FALSE_LATCH]]:
132 ; CHECK-NEXT:   icmp
133 ; CHECK-NEXT:   add
134 ; CHECK-NEXT:   br {{.*}} label %[[FALSE_HEADER]]
136 entry:
137   br label %loop.header
139 loop.header:
140   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
141   %lv = load i32, i32* %ptr
142   %sc = icmp eq i32 %lv, 100
143   br i1 %sc, label %clobber, label %noclobber
145 clobber:
146   call void @clobber()
147   br label %loop.latch
149 noclobber:
150   br label %loop.latch
152 loop.latch:
153   %c = icmp ult i32 %iv, %N
154   %iv.next = add i32 %iv, 1
155   br i1 %c, label %loop.header, label %exit
157 exit:
158   ret i32 10
161 define i32 @partial_unswtich_gep_load_icmp(i32** %ptr, i32 %N) {
162 ; CHECK-LABEL: @partial_unswtich_gep_load_icmp
163 ; CHECK-LABEL: entry:
164 ; CHECK-NEXT:   [[GEP:%[a-z.0-9]+]] = getelementptr i32*, i32** %ptr, i32 1
165 ; CHECK-NEXT:   [[LV0:%[a-z.0-9]+]] = load i32*, i32** [[GEP]]
166 ; CHECK-NEXT:   [[LV1:%[a-z.0-9]+]] = load i32, i32* [[LV0]]
167 ; CHECK-NEXT:   [[C:%[a-z.0-9]+]] = icmp eq i32 [[LV1]], 100
168 ; CHECK-NEXT:   br i1 [[C]], label %[[SPLIT_TRUE_PH:[a-z._]+]], label %[[FALSE_CRIT:[a-z._]+]]
170 ; CHECK:      [[FALSE_CRIT]]:
171 ; CHECK-NEXT:   br label %[[FALSE_PH:[a-z.]+]]
173 ; CHECK:      [[SPLIT_TRUE_PH]]:
174 ; CHECK-NEXT:   br label %[[TRUE_HEADER:[a-z.]+]]
176 ; CHECK: [[TRUE_HEADER]]:
177 ; CHECK-NEXT:   phi i32
178 ; CHECK-NEXT:   [[TRUE_GEP:%[a-z.0-9]+]] = getelementptr i32*, i32** %ptr, i32 1
179 ; CHECK-NEXT:   [[TRUE_LV0:%[a-z.0-9]+]] = load i32*, i32** [[TRUE_GEP]]
180 ; CHECK-NEXT:   [[TRUE_LV1:%[a-z.0-9]+]] = load i32, i32* [[TRUE_LV0]]
181 ; CHECK-NEXT:   [[TRUE_C:%[a-z.0-9]+]] = icmp eq i32 [[TRUE_LV1]], 100
182 ; CHECK-NEXT:   br i1 true, label %[[TRUE_NOCLOBBER:.+]], label %[[TRUE_CLOBBER:[a-z0-9._]+]]
184 ; CHECK: [[TRUE_CLOBBER]]:
185 ; CHECK-NEXT:  call
186 ; CHECK-NEXT:  br label %[[TRUE_LATCH:[a-z0-9._]+]]
188 ; CHECK: [[TRUE_NOCLOBBER]]:
189 ; CHECK-NEXT:  br label %[[TRUE_LATCH:[a-z0-9._]+]]
191 ; CHECK: [[TRUE_LATCH]]:
192 ; CHECK-NEXT:   icmp
193 ; CHECK-NEXT:   add
194 ; CHECK-NEXT:   br {{.*}} label %[[TRUE_HEADER]]
196 ; CHECK:      [[FALSE_PH]]:
197 ; CHECK-NEXT:   br label %[[FALSE_HEADER:[a-z.]+]]
199 ; CHECK: [[FALSE_HEADER]]:
200 ; CHECK-NEXT:   phi i32
201 ; CHECK-NEXT:   [[FALSE_GEP:%[a-z.0-9]+]] = getelementptr i32*, i32** %ptr, i32 1
202 ; CHECK-NEXT:   [[FALSE_LV0:%[a-z.0-9]+]] = load i32*, i32** [[FALSE_GEP]]
203 ; CHECK-NEXT:   [[FALSE_LV1:%[a-z.0-9]+]] = load i32, i32* [[FALSE_LV0]]
204 ; CHECK-NEXT:   [[FALSE_C:%[a-z.0-9]+]] = icmp eq i32 [[FALSE_LV1]], 100
205 ; CHECK-NEXT:   br i1 [[FALSE_C]], label  %[[FALSE_NOCLOBBER:.+]], label %[[FALSE_CLOBBER:[a-z0-9._]+]]
207 ; CHECK: [[FALSE_NOCLOBBER]]:
208 ; CHECK-NEXT:  br label %[[FALSE_LATCH:[a-z0-9._]+]]
210 ; CHECK: [[FALSE_CLOBBER]]:
211 ; CHECK-NEXT:  call
212 ; CHECK-NEXT:  br label %[[FALSE_LATCH:[a-z0-9._]+]]
215 ; CHECK: [[FALSE_LATCH]]:
216 ; CHECK-NEXT:   icmp
217 ; CHECK-NEXT:   add
218 ; CHECK-NEXT:   br {{.*}} label %[[FALSE_HEADER]]
220 entry:
221   br label %loop.header
223 loop.header:
224   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
225   %gep = getelementptr i32*, i32** %ptr, i32 1
226   %lv.1 = load i32*, i32** %gep
227   %lv = load i32, i32* %lv.1
228   %sc = icmp eq i32 %lv, 100
229   br i1 %sc, label %noclobber, label %clobber
231 noclobber:
232   br label %loop.latch
234 clobber:
235   call void @clobber()
236   br label %loop.latch
238 loop.latch:
239   %c = icmp ult i32 %iv, %N
240   %iv.next = add i32 %iv, 1
241   br i1 %c, label %loop.header, label %exit
243 exit:
244   ret i32 10
247 define i32 @partial_unswitch_reduction_phi(i32* %ptr, i32 %N) {
248 ; CHECK-LABEL: @partial_unswitch_reduction_phi
249 ; CHECK-LABEL: entry:
250 ; CHECK-NEXT:   [[LV:%[0-9]+]] = load i32, i32* %ptr, align 4
251 ; CHECK-NEXT:   [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
252 ; CHECK-NEXT:   br i1 [[C]], label %[[SPLIT_TRUE_PH:[a-z._]+]], label %[[FALSE_CRIT:[a-z._]+]]
254 ; CHECK:      [[FALSE_CRIT]]:
255 ; CHECK-NEXT:   br label %[[FALSE_PH:[a-z.]+]]
257 ; CHECK:      [[SPLIT_TRUE_PH]]:
258 ; CHECK-NEXT:   br label %[[TRUE_HEADER:[a-z.]+]]
260 ; CHECK: [[TRUE_HEADER]]:
261 ; CHECK-NEXT:   phi i32
262 ; CHECK-NEXT:    [[TRUE_RED:%[a-z.0-9]+]] = phi i32 [ 20, %[[SPLIT_TRUE_PH]] ], [ [[TRUE_RED_NEXT:%[a-z.0-9]+]], %[[TRUE_LATCH:[a-z.0-9]+]]
263 ; CHECK-NEXT:    [[TRUE_LV:%[a-z.0-9]+]] = load i32, i32* %ptr, align 4
264 ; CHECK-NEXT:    [[TRUE_C:%[a-z.0-9]+]] = icmp eq i32 [[TRUE_LV]], 100
265 ; CHECK-NEXT:    br i1 [[TRUE_C]], label %[[TRUE_CLOBBER:.+]], label %[[TRUE_NOCLOBBER:[a-z0-9._]+]]
267 ; CHECK: [[TRUE_NOCLOBBER]]:
268 ; CHECK-NEXT:  [[TRUE_ADD10:%.+]] = add i32 [[TRUE_RED]], 10
269 ; CHECK-NEXT:  br label %[[TRUE_LATCH]]
271 ; CHECK: [[TRUE_CLOBBER]]:
272 ; CHECK-NEXT:  call
273 ; CHECK-NEXT:  [[TRUE_ADD5:%.+]] = add i32 [[TRUE_RED]], 5
274 ; CHECK-NEXT:  br label %[[TRUE_LATCH]]
276 ; CHECK: [[TRUE_LATCH]]:
277 ; CHECK-NEXT:   [[TRUE_RED_NEXT]] = phi i32 [ [[TRUE_ADD5]], %[[TRUE_CLOBBER]] ], [ [[TRUE_ADD10]], %[[TRUE_NOCLOBBER]] ]
278 ; CHECK-NEXT:   icmp
279 ; CHECK-NEXT:   add
280 ; CHECK-NEXT:   br {{.*}} label %[[TRUE_HEADER]]
283 ; CHECK:      [[FALSE_PH]]:
284 ; CHECK-NEXT:   br label %[[FALSE_HEADER:[a-z.]+]]
286 ; CHECK: [[FALSE_HEADER]]:
287 ; CHECK-NEXT:   phi i32
288 ; CHECK-NEXT:    [[FALSE_RED:%[a-z.0-9]+]] = phi i32 [ 20, %[[FALSE_PH]] ], [ [[FALSE_RED_NEXT:%[a-z.0-9]+]], %[[FALSE_LATCH:[a-z.0-9]+]]
289 ; CHECK-NEXT:    [[FALSE_LV:%[a-z.0-9]+]] = load i32, i32* %ptr, align 4
290 ; CHECK-NEXT:    [[FALSE_C:%[a-z.0-9]+]] = icmp eq i32 [[FALSE_LV]], 100
291 ; CHECK-NEXT:     br i1 false, label  %[[FALSE_CLOBBER:.+]], label %[[FALSE_NOCLOBBER:[a-z0-9._]+]]
293 ; CHECK: [[FALSE_CLOBBER]]:
294 ; CHECK-NEXT:  call
295 ; CHECK-NEXT:  [[FALSE_ADD5:%.+]] = add i32 [[FALSE_RED]], 5
296 ; CHECK-NEXT:  br label %[[FALSE_LATCH:[a-z0-9._]+]]
298 ; CHECK: [[FALSE_NOCLOBBER]]:
299 ; CHECK-NEXT:  [[FALSE_ADD10:%.+]] = add i32 [[FALSE_RED]], 10
300 ; CHECK-NEXT:  br label %[[FALSE_LATCH:[a-z0-9._]+]]
302 ; CHECK: [[FALSE_LATCH]]:
303 ; CHECK-NEXT:   [[FALSE_RED_NEXT]] = phi i32 [ [[FALSE_ADD5]], %[[FALSE_CLOBBER]] ], [ [[FALSE_ADD10]], %[[FALSE_NOCLOBBER]] ]
304 ; CHECK-NEXT:   icmp
305 ; CHECK-NEXT:   add
306 ; CHECK-NEXT:   br {{.*}} label %[[FALSE_HEADER]]
308 entry:
309   br label %loop.header
311 loop.header:
312   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
313   %red = phi i32 [ 20, %entry ], [ %red.next, %loop.latch ]
314   %lv = load i32, i32* %ptr
315   %sc = icmp eq i32 %lv, 100
316   br i1 %sc, label %clobber, label %noclobber
318 clobber:
319   call void @clobber()
320   %add.5 = add i32 %red, 5
321   br label %loop.latch
323 noclobber:
324   %add.10 = add i32 %red, 10
325   br label %loop.latch
327 loop.latch:
328   %red.next = phi i32 [ %add.5, %clobber ], [ %add.10, %noclobber ]
329   %c = icmp ult i32 %iv, %N
330   %iv.next = add i32 %iv, 1
331   br i1 %c, label %loop.header, label %exit
333 exit:
334   %red.next.lcssa = phi i32 [ %red.next, %loop.latch ]
335   ret i32 %red.next.lcssa
338 ; Partial unswitching is possible, because the store in %noclobber does not
339 ; alias the load of the condition.
340 define i32 @partial_unswitch_true_successor_noclobber(i32* noalias %ptr.1, i32* noalias %ptr.2, i32 %N) {
341 ; CHECK-LABEL: @partial_unswitch_true_successor
342 ; CHECK-NEXT:  entry:
343 ; CHECK-NEXT:   [[LV:%[0-9]+]] = load i32, i32* %ptr.1, align 4
344 ; CHECK-NEXT:   [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
345 ; CHECK-NEXT:   br i1 [[C]], label %[[SPLIT_TRUE_PH:[a-z._]+]], label %[[FALSE_CRIT:[a-z._]+]]
347 ; CHECK:      [[FALSE_CRIT]]:
348 ; CHECK-NEXT:   br label %[[FALSE_PH:[a-z.]+]]
350 ; CHECK:      [[SPLIT_TRUE_PH]]:
351 ; CHECK-NEXT:   br label %[[TRUE_HEADER:[a-z.]+]]
353 ; CHECK: [[TRUE_HEADER]]:
354 ; CHECK-NEXT:   phi i32
355 ; CHECK-NEXT:    [[TRUE_LV:%[a-z.0-9]+]] = load i32, i32* %ptr.1, align 4
356 ; CHECK-NEXT:    [[TRUE_C:%[a-z.0-9]+]] = icmp eq i32 [[TRUE_LV]], 100
357 ; CHECK-NEXT:    br i1 true, label %[[TRUE_NOCLOBBER:.+]], label %[[TRUE_CLOBBER:[a-z0-9._]+]]
359 ; CHECK: [[TRUE_CLOBBER]]:
360 ; CHECK-NEXT:  call
361 ; CHECK-NEXT:  br label %[[TRUE_LATCH:[a-z0-9._]+]]
363 ; CHECK: [[TRUE_NOCLOBBER]]:
364 ; CHECK-NEXT:  [[TRUE_GEP:%[a-z0-9._]+]]  = getelementptr i32, i32* %ptr.2
365 ; CHECK-NEXT:  store i32 [[TRUE_LV]], i32* [[TRUE_GEP]], align 4
366 ; CHECK-NEXT:  br label %[[TRUE_LATCH:[a-z0-9._]+]]
368 ; CHECK: [[TRUE_LATCH]]:
369 ; CHECK-NEXT:   icmp
370 ; CHECK-NEXT:   add
371 ; CHECK-NEXT:   br {{.*}} label %[[TRUE_HEADER]]
374 ; CHECK:      [[FALSE_PH]]:
375 ; CHECK-NEXT:   br label %[[FALSE_HEADER:[a-z.]+]]
377 ; CHECK: [[FALSE_HEADER]]:
378 ; CHECK-NEXT:   phi i32
379 ; CHECK-NEXT:    [[FALSE_LV:%[a-z.0-9]+]] = load i32, i32* %ptr.1, align 4
380 ; CHECK-NEXT:    [[FALSE_C:%[a-z.0-9]+]] = icmp eq i32 [[FALSE_LV]], 100
381 ; CHECK-NEXT:     br i1 [[FALSE_C]], label  %[[FALSE_NOCLOBBER:.+]], label %[[FALSE_CLOBBER:[a-z0-9._]+]]
383 ; CHECK: [[FALSE_NOCLOBBER]]:
384 ; CHECK-NEXT:  [[FALSE_GEP:%[a-z0-9._]+]]  = getelementptr i32, i32* %ptr.2
385 ; CHECK-NEXT:  store i32 [[FALSE_LV]], i32* [[FALSE_GEP]], align 4
386 ; CHECK-NEXT:  br label %[[FALSE_LATCH:[a-z0-9._]+]]
388 ; CHECK: [[FALSE_CLOBBER]]:
389 ; CHECK-NEXT:  call
390 ; CHECK-NEXT:  br label %[[FALSE_LATCH:[a-z0-9._]+]]
392 ; CHECK: [[FALSE_LATCH]]:
393 ; CHECK-NEXT:   icmp
394 ; CHECK-NEXT:   add
395 ; CHECK-NEXT:   br {{.*}} label %[[FALSE_HEADER]]
397 entry:
398   br label %loop.header
400 loop.header:
401   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
402   %lv = load i32, i32* %ptr.1
403   %sc = icmp eq i32 %lv, 100
404   br i1 %sc, label %noclobber, label %clobber
406 noclobber:
407   %gep.1 = getelementptr i32, i32* %ptr.2, i32 %iv
408   store i32 %lv, i32* %gep.1
409   br label %loop.latch
411 clobber:
412   call void @clobber()
413   br label %loop.latch
415 loop.latch:
416   %c = icmp ult i32 %iv, %N
417   %iv.next = add i32 %iv, 1
418   br i1 %c, label %loop.header, label %exit
420 exit:
421   ret i32 10
424 define void @no_partial_unswitch_phi_cond(i1 %lc, i32 %N) {
425 ; CHECK-LABEL: @no_partial_unswitch_phi_cond
426 ; CHECK-NEXT:  entry:
427 ; CHECK-NEXT:    br label %loop.header
429 entry:
430   br label %loop.header
432 loop.header:
433   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
434   %sc = phi i1 [ %lc, %entry ], [ true, %loop.latch ]
435   br i1 %sc, label %clobber, label %noclobber
437 clobber:
438   call void @clobber()
439   br label %loop.latch
441 noclobber:
442   br label %loop.latch
444 loop.latch:
445   %c = icmp ult i32 %iv, %N
446   %iv.next = add i32 %iv, 1
447   br i1 %c, label %loop.header, label %exit
449 exit:
450   ret void
453 define void @no_partial_unswitch_clobber_latch(i32* %ptr, i32 %N) {
454 ; CHECK-LABEL: @no_partial_unswitch_clobber_latch
455 ; CHECK-NEXT:  entry:
456 ; CHECK-NEXT:    br label %loop.header
458 entry:
459   br label %loop.header
461 loop.header:
462   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
463   %lv = load i32, i32* %ptr
464   %sc = icmp eq i32 %lv, 100
465   br i1 %sc, label %noclobber, label %clobber
467 noclobber:
468   br label %loop.latch
470 clobber:
471   call void @clobber()
472   br label %loop.latch
474 loop.latch:
475   call void @clobber()
476   %c = icmp ult i32 %iv, %N
477   %iv.next = add i32 %iv, 1
478   br i1 %c, label %loop.header, label %exit
480 exit:
481   ret void
484 define void @no_partial_unswitch_clobber_header(i32* %ptr, i32 %N) {
485 ; CHECK-LABEL: @no_partial_unswitch_clobber_header
486 ; CHECK-NEXT:  entry:
487 ; CHECK-NEXT:    br label %loop.header
489 entry:
490   br label %loop.header
492 loop.header:
493   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
494   call void @clobber()
495   %lv = load i32, i32* %ptr
496   %sc = icmp eq i32 %lv, 100
497   br i1 %sc, label %noclobber, label %clobber
499 noclobber:
500   br label %loop.latch
502 clobber:
503   call void @clobber()
504   br label %loop.latch
506 loop.latch:
507   %c = icmp ult i32 %iv, %N
508   %iv.next = add i32 %iv, 1
509   br i1 %c, label %loop.header, label %exit
511 exit:
512   ret void
515 define void @no_partial_unswitch_clobber_both(i32* %ptr, i32 %N) {
516 ; CHECK-LABEL: @no_partial_unswitch_clobber_both
517 ; CHECK-NEXT:  entry:
518 ; CHECK-NEXT:    br label %loop.header
520 entry:
521   br label %loop.header
523 loop.header:
524   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
525   %lv = load i32, i32* %ptr
526   %sc = icmp eq i32 %lv, 100
527   br i1 %sc, label %noclobber, label %clobber
529 noclobber:
530   call void @clobber()
531   br label %loop.latch
533 clobber:
534   call void @clobber()
535   br label %loop.latch
537 loop.latch:
538   %c = icmp ult i32 %iv, %N
539   %iv.next = add i32 %iv, 1
540   br i1 %c, label %loop.header, label %exit
542 exit:
543   ret void
546 define i32 @no_partial_unswitch_true_successor_storeclobber(i32* %ptr.1, i32* %ptr.2, i32 %N) {
547 ; CHECK-LABEL: @no_partial_unswitch_true_successor_storeclobber
548 ; CHECK-NEXT:  entry:
549 ; CHECK-NEXT:    br label %loop.header
551 entry:
552   br label %loop.header
554 loop.header:
555   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
556   %lv = load i32, i32* %ptr.1
557   %sc = icmp eq i32 %lv, 100
558   br i1 %sc, label %noclobber, label %clobber
560 noclobber:
561   %gep.1 = getelementptr i32, i32* %ptr.2, i32 %iv
562   store i32 %lv, i32* %gep.1
563   br label %loop.latch
565 clobber:
566   call void @clobber()
567   br label %loop.latch
569 loop.latch:
570   %c = icmp ult i32 %iv, %N
571   %iv.next = add i32 %iv, 1
572   br i1 %c, label %loop.header, label %exit
574 exit:
575   ret i32 10
578 ; Make sure the duplicated instructions are moved to a preheader that always
579 ; executes when the loop body also executes. Do not check the unswitched code,
580 ; because it is already checked in the @partial_unswitch_true_successor test
581 ; case.
582 define i32 @partial_unswitch_true_successor_preheader_insertion(i32* %ptr, i32 %N) {
583 ; CHECK-LABEL: @partial_unswitch_true_successor_preheader_insertion(
584 ; CHECK-NEXT:  entry:
585 ; CHECK-NEXT:   [[EC:%[a-z]+]] = icmp ne i32* %ptr, null
586 ; CHECK-NEXT:   br i1 [[EC]], label %[[PH:[a-z0-9.]+]], label %[[EXIT:[a-z0-9.]+]]
588 ; CHECK: [[PH]]:
589 ; CHECK-NEXT:   [[LV:%[0-9]+]] = load i32, i32* %ptr, align 4
590 ; CHECK-NEXT:   [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
591 ; CHECK-NEXT:   br i1 [[C]]
593 entry:
594   %ec = icmp ne i32* %ptr, null
595   br i1 %ec, label %loop.ph, label %exit
597 loop.ph:
598   br label %loop.header
600 loop.header:
601   %iv = phi i32 [ 0, %loop.ph ], [ %iv.next, %loop.latch ]
602   %lv = load i32, i32* %ptr
603   %sc = icmp eq i32 %lv, 100
604   br i1 %sc, label %noclobber, label %clobber
606 noclobber:
607   br label %loop.latch
609 clobber:
610   call void @clobber()
611   br label %loop.latch
613 loop.latch:
614   %c = icmp ult i32 %iv, %N
615   %iv.next = add i32 %iv, 1
616   br i1 %c, label %loop.header, label %exit
618 exit:
619   ret i32 10
622 ; Make sure the duplicated instructions are hoisted just before the branch of
623 ; the preheader. Do not check the unswitched code, because it is already checked
624 ; in the @partial_unswitch_true_successor test case
625 define i32 @partial_unswitch_true_successor_insert_point(i32* %ptr, i32 %N) {
626 ; CHECK-LABEL: @partial_unswitch_true_successor_insert_point(
627 ; CHECK-NEXT:  entry:
628 ; CHECK-NEXT:   call void @clobber()
629 ; CHECK-NEXT:   [[LV:%[0-9]+]] = load i32, i32* %ptr, align 4
630 ; CHECK-NEXT:   [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
631 ; CHECK-NEXT:   br i1 [[C]]
633 entry:
634   call void @clobber()
635   br label %loop.header
637 loop.header:
638   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
639   %lv = load i32, i32* %ptr
640   %sc = icmp eq i32 %lv, 100
641   br i1 %sc, label %noclobber, label %clobber
643 noclobber:
644   br label %loop.latch
646 clobber:
647   call void @clobber()
648   br label %loop.latch
650 loop.latch:
651   %c = icmp ult i32 %iv, %N
652   %iv.next = add i32 %iv, 1
653   br i1 %c, label %loop.header, label %exit
655 exit:
656   ret i32 10
659 ; Make sure invariant instructions in the loop are also hoisted to the preheader.
660 ; Do not check the unswitched code, because it is already checked in the
661 ; @partial_unswitch_true_successor test case
662 define i32 @partial_unswitch_true_successor_hoist_invariant(i32* %ptr, i32 %N) {
663 ; CHECK-LABEL: @partial_unswitch_true_successor_hoist_invariant(
664 ; CHECK-NEXT:  entry:
665 ; CHECK-NEXT:   [[GEP:%[0-9]+]] = getelementptr i32, i32* %ptr, i64 1
666 ; CHECK-NEXT:   [[LV:%[0-9]+]] = load i32, i32* [[GEP]], align 4
667 ; CHECK-NEXT:   [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
668 ; CHECK-NEXT:   br i1 [[C]]
670 entry:
671   br label %loop.header
673 loop.header:
674   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
675   %gep = getelementptr i32, i32* %ptr, i64 1
676   %lv = load i32, i32* %gep
677   %sc = icmp eq i32 %lv, 100
678   br i1 %sc, label %noclobber, label %clobber
680 noclobber:
681   br label %loop.latch
683 clobber:
684   call void @clobber()
685   br label %loop.latch
687 loop.latch:
688   %c = icmp ult i32 %iv, %N
689   %iv.next = add i32 %iv, 1
690   br i1 %c, label %loop.header, label %exit
692 exit:
693   ret i32 10
696 ; Do not unswitch if the condition depends on an atomic load. Duplicating such
697 ; loads is not safe.
698 define i32 @no_partial_unswitch_atomic_load_unordered(i32* %ptr, i32 %N) {
699 ; CHECK-LABEL: @no_partial_unswitch_atomic_load_unordered
700 ; CHECK-NEXT:  entry:
701 ; CHECK-NEXT:    br label %loop.header
703 entry:
704   br label %loop.header
706 loop.header:
707   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
708   %lv = load atomic i32, i32* %ptr unordered, align 4
709   %sc = icmp eq i32 %lv, 100
710   br i1 %sc, label %noclobber, label %clobber
712 noclobber:
713   br label %loop.latch
715 clobber:
716   call void @clobber()
717   br label %loop.latch
719 loop.latch:
720   %c = icmp ult i32 %iv, %N
721   %iv.next = add i32 %iv, 1
722   br i1 %c, label %loop.header, label %exit
724 exit:
725   ret i32 10
728 ; Do not unswitch if the condition depends on an atomic load. Duplicating such
729 ; loads is not safe.
730 define i32 @no_partial_unswitch_atomic_load_monotonic(i32* %ptr, i32 %N) {
731 ; CHECK-LABEL: @no_partial_unswitch_atomic_load_monotonic
732 ; CHECK-NEXT:  entry:
733 ; CHECK-NEXT:    br label %loop.header
735 entry:
736   br label %loop.header
738 loop.header:
739   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
740   %lv = load atomic i32, i32* %ptr monotonic, align 4
741   %sc = icmp eq i32 %lv, 100
742   br i1 %sc, label %noclobber, label %clobber
744 noclobber:
745   br label %loop.latch
747 clobber:
748   call void @clobber()
749   br label %loop.latch
751 loop.latch:
752   %c = icmp ult i32 %iv, %N
753   %iv.next = add i32 %iv, 1
754   br i1 %c, label %loop.header, label %exit
756 exit:
757   ret i32 10
761 declare i32 @get_value()
763 ; Do not unswitch if the condition depends on a call, that may clobber memory.
764 ; Duplicating such a call is not safe.
765 define i32 @no_partial_unswitch_cond_call(i32* %ptr, i32 %N) {
766 ; CHECK-LABEL: @no_partial_unswitch_cond_call
767 ; CHECK-NEXT:  entry:
768 ; CHECK-NEXT:    br label %loop.header
770 entry:
771   br label %loop.header
773 loop.header:
774   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
775   %lv = call i32 @get_value()
776   %sc = icmp eq i32 %lv, 100
777   br i1 %sc, label %noclobber, label %clobber
779 noclobber:
780   br label %loop.latch
782 clobber:
783   call void @clobber()
784   br label %loop.latch
786 loop.latch:
787   %c = icmp ult i32 %iv, %N
788   %iv.next = add i32 %iv, 1
789   br i1 %c, label %loop.header, label %exit
791 exit:
792   ret i32 10
795 define i32 @no_partial_unswitch_true_successor_exit(i32* %ptr, i32 %N) {
796 ; CHECK-LABEL: @no_partial_unswitch_true_successor_exit
797 ; CHECK-LABEL: entry:
798 ; CHECK-NEXT:   br label %loop.header
800 entry:
801   br label %loop.header
803 loop.header:
804   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
805   %lv = load i32, i32* %ptr
806   %sc = icmp eq i32 %lv, 100
807   br i1 %sc, label %exit, label %clobber
809 clobber:
810   call void @clobber()
811   br label %loop.latch
813 loop.latch:
814   %c = icmp ult i32 %iv, %N
815   %iv.next = add i32 %iv, 1
816   br i1 %c, label %loop.header, label %exit
818 exit:
819   ret i32 10
822 define i32 @no_partial_unswitch_true_same_successor(i32* %ptr, i32 %N) {
823 ; CHECK-LABEL: @no_partial_unswitch_true_same_successor
824 ; CHECK-LABEL: entry:
825 ; CHECK-NEXT:   br label %loop.header
827 entry:
828   br label %loop.header
830 loop.header:
831   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
832   %lv = load i32, i32* %ptr
833   %sc = icmp eq i32 %lv, 100
834   br i1 %sc, label %noclobber, label %noclobber
836 noclobber:
837   br label %loop.latch
839 loop.latch:
840   %c = icmp ult i32 %iv, %N
841   %iv.next = add i32 %iv, 1
842   br i1 %c, label %loop.header, label %exit
844 exit:
845   ret i32 10
848 define i32 @partial_unswitch_true_to_latch(i32* %ptr, i32 %N) {
849 ; CHECK-LABEL: @partial_unswitch_true_to_latch
850 ; CHECK-LABEL: entry:
851 ; CHECK-NEXT:   [[LV:%[0-9]+]] = load i32, i32* %ptr, align 4
852 ; CHECK-NEXT:   [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
853 ; CHECK-NEXT:   br i1 [[C]],
855 entry:
856   br label %loop.header
858 loop.header:
859   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
860   %lv = load i32, i32* %ptr
861   %sc = icmp eq i32 %lv, 100
862   br i1 %sc, label %loop.latch, label %clobber
864 clobber:
865   call void @clobber()
866   br label %loop.latch
868 loop.latch:
869   %c = icmp ult i32 %iv, %N
870   %iv.next = add i32 %iv, 1
871   br i1 %c, label %loop.header, label %exit
873 exit:
874   ret i32 10