• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt < %s -gvn-sink -simplifycfg -simplifycfg-sink-common=false -S | FileCheck %s
2
3define zeroext i1 @test1(i1 zeroext %flag, i32 %blksA, i32 %blksB, i32 %nblks) {
4entry:
5  br i1 %flag, label %if.then, label %if.else
6
7; CHECK-LABEL: test1
8; CHECK: add
9; CHECK: select
10; CHECK: icmp
11; CHECK-NOT: br
12if.then:
13  %cmp = icmp uge i32 %blksA, %nblks
14  %frombool1 = zext i1 %cmp to i8
15  br label %if.end
16
17if.else:
18  %add = add i32 %nblks, %blksB
19  %cmp2 = icmp ule i32 %add, %blksA
20  %frombool3 = zext i1 %cmp2 to i8
21  br label %if.end
22
23if.end:
24  %obeys.0 = phi i8 [ %frombool1, %if.then ], [ %frombool3, %if.else ]
25  %tobool4 = icmp ne i8 %obeys.0, 0
26  ret i1 %tobool4
27}
28
29define zeroext i1 @test2(i1 zeroext %flag, i32 %blksA, i32 %blksB, i32 %nblks) {
30entry:
31  br i1 %flag, label %if.then, label %if.else
32
33; CHECK-LABEL: test2
34; CHECK: add
35; CHECK: select
36; CHECK: icmp
37; CHECK-NOT: br
38if.then:
39  %cmp = icmp uge i32 %blksA, %nblks
40  %frombool1 = zext i1 %cmp to i8
41  br label %if.end
42
43if.else:
44  %add = add i32 %nblks, %blksB
45  %cmp2 = icmp uge i32 %blksA, %add
46  %frombool3 = zext i1 %cmp2 to i8
47  br label %if.end
48
49if.end:
50  %obeys.0 = phi i8 [ %frombool1, %if.then ], [ %frombool3, %if.else ]
51  %tobool4 = icmp ne i8 %obeys.0, 0
52  ret i1 %tobool4
53}
54
55declare i32 @foo(i32, i32) nounwind readnone
56
57; FIXME: The test failes when the original order of the
58; candidates with the same cost is preserved.
59;
60;define i32 @test3(i1 zeroext %flag, i32 %x, i32 %y) {
61;entry:
62;  br i1 %flag, label %if.then, label %if.else
63;
64;if.then:
65;  %x0 = call i32 @foo(i32 %x, i32 0) nounwind readnone
66;  %y0 = call i32 @foo(i32 %x, i32 1) nounwind readnone
67;  br label %if.end
68;
69;if.else:
70;  %x1 = call i32 @foo(i32 %y, i32 0) nounwind readnone
71;  %y1 = call i32 @foo(i32 %y, i32 1) nounwind readnone
72;  br label %if.end
73;
74;if.end:
75;  %xx = phi i32 [ %x0, %if.then ], [ %x1, %if.else ]
76;  %yy = phi i32 [ %y0, %if.then ], [ %y1, %if.else ]
77;  %ret = add i32 %xx, %yy
78;  ret i32 %ret
79;}
80;
81; -CHECK-LABEL: test3
82; -CHECK: select
83; -CHECK: call
84; -CHECK: call
85; -CHECK: add
86; -CHECK-NOT: br
87
88define i32 @test4(i1 zeroext %flag, i32 %x, i32* %y) {
89entry:
90  br i1 %flag, label %if.then, label %if.else
91
92if.then:
93  %a = add i32 %x, 5
94  store i32 %a, i32* %y
95  br label %if.end
96
97if.else:
98  %b = add i32 %x, 7
99  store i32 %b, i32* %y
100  br label %if.end
101
102if.end:
103  ret i32 1
104}
105
106; CHECK-LABEL: test4
107; CHECK: select
108; CHECK: store
109; CHECK-NOT: store
110
111define i32 @test5(i1 zeroext %flag, i32 %x, i32* %y) {
112entry:
113  br i1 %flag, label %if.then, label %if.else
114
115if.then:
116  %a = add i32 %x, 5
117  store volatile i32 %a, i32* %y
118  br label %if.end
119
120if.else:
121  %b = add i32 %x, 7
122  store i32 %b, i32* %y
123  br label %if.end
124
125if.end:
126  ret i32 1
127}
128
129; CHECK-LABEL: test5
130; CHECK: store volatile
131; CHECK: store
132
133define i32 @test6(i1 zeroext %flag, i32 %x, i32* %y) {
134entry:
135  br i1 %flag, label %if.then, label %if.else
136
137if.then:
138  %a = add i32 %x, 5
139  store volatile i32 %a, i32* %y
140  br label %if.end
141
142if.else:
143  %b = add i32 %x, 7
144  store volatile i32 %b, i32* %y
145  br label %if.end
146
147if.end:
148  ret i32 1
149}
150
151; CHECK-LABEL: test6
152; CHECK: select
153; CHECK: store volatile
154; CHECK-NOT: store
155
156define i32 @test7(i1 zeroext %flag, i32 %x, i32* %y) {
157entry:
158  br i1 %flag, label %if.then, label %if.else
159
160if.then:
161  %z = load volatile i32, i32* %y
162  %a = add i32 %z, 5
163  store volatile i32 %a, i32* %y
164  br label %if.end
165
166if.else:
167  %w = load volatile i32, i32* %y
168  %b = add i32 %w, 7
169  store volatile i32 %b, i32* %y
170  br label %if.end
171
172if.end:
173  ret i32 1
174}
175
176; CHECK-LABEL: test7
177; CHECK-DAG: select
178; CHECK-DAG: load volatile
179; CHECK: store volatile
180; CHECK-NOT: load
181; CHECK-NOT: store
182
183; The extra store in %if.then means %z and %w are not equivalent.
184define i32 @test9(i1 zeroext %flag, i32 %x, i32* %y, i32* %p) {
185entry:
186  br i1 %flag, label %if.then, label %if.else
187
188if.then:
189  store i32 7, i32* %p
190  %z = load volatile i32, i32* %y
191  store i32 6, i32* %p
192  %a = add i32 %z, 5
193  store volatile i32 %a, i32* %y
194  br label %if.end
195
196if.else:
197  %w = load volatile i32, i32* %y
198  %b = add i32 %w, 7
199  store volatile i32 %b, i32* %y
200  br label %if.end
201
202if.end:
203  ret i32 1
204}
205
206; CHECK-LABEL: test9
207; CHECK: add
208; CHECK: add
209
210%struct.anon = type { i32, i32 }
211
212; The GEP indexes a struct type so cannot have a variable last index.
213define i32 @test10(i1 zeroext %flag, i32 %x, i32* %y, %struct.anon* %s) {
214entry:
215  br i1 %flag, label %if.then, label %if.else
216
217if.then:
218  %dummy = add i32 %x, 5
219  %gepa = getelementptr inbounds %struct.anon, %struct.anon* %s, i32 0, i32 0
220  store volatile i32 %x, i32* %gepa
221  br label %if.end
222
223if.else:
224  %dummy1 = add i32 %x, 6
225  %gepb = getelementptr inbounds %struct.anon, %struct.anon* %s, i32 0, i32 1
226  store volatile i32 %x, i32* %gepb
227  br label %if.end
228
229if.end:
230  ret i32 1
231}
232
233; CHECK-LABEL: test10
234; CHECK: getelementptr
235; CHECK: store volatile
236; CHECK: getelementptr
237; CHECK: store volatile
238
239; The shufflevector's mask operand cannot be merged in a PHI.
240define i32 @test11(i1 zeroext %flag, i32 %w, <2 x i32> %x, <2 x i32> %y) {
241entry:
242  br i1 %flag, label %if.then, label %if.else
243
244if.then:
245  %dummy = add i32 %w, 5
246  %sv1 = shufflevector <2 x i32> %x, <2 x i32> %y, <2 x i32> <i32 0, i32 1>
247  br label %if.end
248
249if.else:
250  %dummy1 = add i32 %w, 6
251  %sv2 = shufflevector <2 x i32> %x, <2 x i32> %y, <2 x i32> <i32 1, i32 0>
252  br label %if.end
253
254if.end:
255  %p = phi <2 x i32> [ %sv1, %if.then ], [ %sv2, %if.else ]
256  ret i32 1
257}
258
259; CHECK-LABEL: test11
260; CHECK: shufflevector
261; CHECK: shufflevector
262
263; We can't common an intrinsic!
264define i32 @test12(i1 zeroext %flag, i32 %w, i32 %x, i32 %y) {
265entry:
266  br i1 %flag, label %if.then, label %if.else
267
268if.then:
269  %dummy = add i32 %w, 5
270  %sv1 = call i32 @llvm.ctlz.i32(i32 %x)
271  br label %if.end
272
273if.else:
274  %dummy1 = add i32 %w, 6
275  %sv2 = call i32 @llvm.cttz.i32(i32 %x)
276  br label %if.end
277
278if.end:
279  %p = phi i32 [ %sv1, %if.then ], [ %sv2, %if.else ]
280  ret i32 1
281}
282
283declare i32 @llvm.ctlz.i32(i32 %x) readnone
284declare i32 @llvm.cttz.i32(i32 %x) readnone
285
286; CHECK-LABEL: test12
287; CHECK: call i32 @llvm.ctlz
288; CHECK: call i32 @llvm.cttz
289
290; The TBAA metadata should be properly combined.
291define i32 @test13(i1 zeroext %flag, i32 %x, i32* %y) {
292entry:
293  br i1 %flag, label %if.then, label %if.else
294
295if.then:
296  %z = load volatile i32, i32* %y
297  %a = add i32 %z, 5
298  store volatile i32 %a, i32* %y, !tbaa !3
299  br label %if.end
300
301if.else:
302  %w = load volatile i32, i32* %y
303  %b = add i32 %w, 7
304  store volatile i32 %b, i32* %y, !tbaa !4
305  br label %if.end
306
307if.end:
308  ret i32 1
309}
310
311!0 = !{ !"an example type tree" }
312!1 = !{ !"int", !0 }
313!2 = !{ !"float", !0 }
314!3 = !{ !"const float", !2, i64 0 }
315!4 = !{ !"special float", !2, i64 1 }
316
317; CHECK-LABEL: test13
318; CHECK-DAG: select
319; CHECK-DAG: load volatile
320; CHECK: store volatile {{.*}}, !tbaa !0
321; CHECK-NOT: load
322; CHECK-NOT: store
323
324; The call should be commoned.
325define i32 @test13a(i1 zeroext %flag, i32 %w, i32 %x, i32 %y) {
326entry:
327  br i1 %flag, label %if.then, label %if.else
328
329if.then:
330  %sv1 = call i32 @bar(i32 %x)
331  br label %if.end
332
333if.else:
334  %sv2 = call i32 @bar(i32 %y)
335  br label %if.end
336
337if.end:
338  %p = phi i32 [ %sv1, %if.then ], [ %sv2, %if.else ]
339  ret i32 1
340}
341declare i32 @bar(i32)
342
343; CHECK-LABEL: test13a
344; CHECK: %[[x:.*]] = select i1 %flag
345; CHECK: call i32 @bar(i32 %[[x]])
346
347; The load should be commoned.
348define i32 @test14(i1 zeroext %flag, i32 %w, i32 %x, i32 %y, %struct.anon* %s) {
349entry:
350  br i1 %flag, label %if.then, label %if.else
351
352if.then:
353  %dummy = add i32 %x, 1
354  %gepa = getelementptr inbounds %struct.anon, %struct.anon* %s, i32 0, i32 1
355  %sv1 = load i32, i32* %gepa
356  %cmp1 = icmp eq i32 %sv1, 56
357  br label %if.end
358
359if.else:
360  %dummy2 = add i32 %x, 4
361  %gepb = getelementptr inbounds %struct.anon, %struct.anon* %s, i32 0, i32 1
362  %sv2 = load i32, i32* %gepb
363  %cmp2 = icmp eq i32 %sv2, 57
364  br label %if.end
365
366if.end:
367  %p = phi i1 [ %cmp1, %if.then ], [ %cmp2, %if.else ]
368  ret i32 1
369}
370
371; CHECK-LABEL: test14
372; CHECK: getelementptr
373; CHECK: load
374; CHECK-NOT: load
375
376; The load should be commoned.
377define i32 @test15(i1 zeroext %flag, i32 %w, i32 %x, i32 %y, %struct.anon* %s) {
378entry:
379  br i1 %flag, label %if.then, label %if.else
380
381if.then:
382  %dummy = add i32 %x, 1
383  %gepa = getelementptr inbounds %struct.anon, %struct.anon* %s, i32 0, i32 0
384  %sv1 = load i32, i32* %gepa
385  %ext1 = zext i32 %sv1 to i64
386  %cmp1 = icmp eq i64 %ext1, 56
387  br label %if.end
388
389if.else:
390  %dummy2 = add i32 %x, 4
391  %gepb = getelementptr inbounds %struct.anon, %struct.anon* %s, i32 0, i32 1
392  %sv2 = load i32, i32* %gepb
393  %ext2 = zext i32 %sv2 to i64
394  %cmp2 = icmp eq i64 %ext2, 56
395  br label %if.end
396
397if.end:
398  %p = phi i1 [ %cmp1, %if.then ], [ %cmp2, %if.else ]
399  ret i32 1
400}
401
402; CHECK-LABEL: test15
403; CHECK: getelementptr
404; CHECK: load
405; CHECK-NOT: load
406
407define zeroext i1 @test_crash(i1 zeroext %flag, i32* %i4, i32* %m, i32* %n) {
408entry:
409  br i1 %flag, label %if.then, label %if.else
410
411if.then:
412  %tmp1 = load i32, i32* %i4
413  %tmp2 = add i32 %tmp1, -1
414  store i32 %tmp2, i32* %i4
415  br label %if.end
416
417if.else:
418  %tmp3 = load i32, i32* %m
419  %tmp4 = load i32, i32* %n
420  %tmp5 = add i32 %tmp3, %tmp4
421  store i32 %tmp5, i32* %i4
422  br label %if.end
423
424if.end:
425  ret i1 true
426}
427
428; CHECK-LABEL: test_crash
429; No checks for test_crash - just ensure it doesn't crash!
430
431define zeroext i1 @test16(i1 zeroext %flag, i1 zeroext %flag2, i32 %blksA, i32 %blksB, i32 %nblks) {
432
433entry:
434  br i1 %flag, label %if.then, label %if.else
435
436if.then:
437  %cmp = icmp uge i32 %blksA, %nblks
438  %frombool1 = zext i1 %cmp to i8
439  br label %if.end
440
441if.else:
442  br i1 %flag2, label %if.then2, label %if.end
443
444if.then2:
445  %add = add i32 %nblks, %blksB
446  %cmp2 = icmp ule i32 %add, %blksA
447  %frombool3 = zext i1 %cmp2 to i8
448  br label %if.end
449
450if.end:
451  %obeys.0 = phi i8 [ %frombool1, %if.then ], [ %frombool3, %if.then2 ], [ 0, %if.else ]
452  %tobool4 = icmp ne i8 %obeys.0, 0
453  ret i1 %tobool4
454}
455
456; CHECK-LABEL: test16
457; CHECK: zext
458; CHECK: zext
459
460define zeroext i1 @test16a(i1 zeroext %flag, i1 zeroext %flag2, i32 %blksA, i32 %blksB, i32 %nblks, i8* %p) {
461
462entry:
463  br i1 %flag, label %if.then, label %if.else
464
465if.then:
466  %cmp = icmp uge i32 %blksA, %nblks
467  %frombool1 = zext i1 %cmp to i8
468  %b1 = sext i8 %frombool1 to i32
469  %b2 = trunc i32 %b1 to i8
470  store i8 %b2, i8* %p
471  br label %if.end
472
473if.else:
474  br i1 %flag2, label %if.then2, label %if.end
475
476if.then2:
477  %add = add i32 %nblks, %blksB
478  %cmp2 = icmp ule i32 %add, %blksA
479  %frombool3 = zext i1 %cmp2 to i8
480  %a1 = sext i8 %frombool3 to i32
481  %a2 = trunc i32 %a1 to i8
482  store i8 %a2, i8* %p
483  br label %if.end
484
485if.end:
486  ret i1 true
487}
488
489; CHECK-LABEL: test16a
490; CHECK: zext
491; CHECK-NOT: zext
492
493define zeroext i1 @test17(i32 %flag, i32 %blksA, i32 %blksB, i32 %nblks) {
494entry:
495  switch i32 %flag, label %if.end [
496    i32 0, label %if.then
497    i32 1, label %if.then2
498  ]
499
500if.then:
501  %cmp = icmp uge i32 %blksA, %nblks
502  %frombool1 = call i8 @i1toi8(i1 %cmp)
503  %a1 = sext i8 %frombool1 to i32
504  %a2 = trunc i32 %a1 to i8
505  br label %if.end
506
507if.then2:
508  %add = add i32 %nblks, %blksB
509  %cmp2 = icmp ule i32 %add, %blksA
510  %frombool3 = call i8 @i1toi8(i1 %cmp2)
511  %b1 = sext i8 %frombool3 to i32
512  %b2 = trunc i32 %b1 to i8
513  br label %if.end
514
515if.end:
516  %obeys.0 = phi i8 [ %a2, %if.then ], [ %b2, %if.then2 ], [ 0, %entry ]
517  %tobool4 = icmp ne i8 %obeys.0, 0
518  ret i1 %tobool4
519}
520declare i8 @i1toi8(i1)
521
522; FIXME: DISABLED - we don't consider this profitable. We should
523;  - Consider argument setup/return mov'ing for calls, like InlineCost does.
524;  - Consider the removal of the %obeys.0 PHI (zero PHI movement overall)
525
526; DISABLED-CHECK-LABEL: test17
527; DISABLED-CHECK: if.then:
528; DISABLED-CHECK-NEXT: icmp uge
529; DISABLED-CHECK-NEXT: br label %[[x:.*]]
530
531; DISABLED-CHECK: if.then2:
532; DISABLED-CHECK-NEXT: add
533; DISABLED-CHECK-NEXT: icmp ule
534; DISABLED-CHECK-NEXT: br label %[[x]]
535
536; DISABLED-CHECK: [[x]]:
537; DISABLED-CHECK-NEXT: %[[y:.*]] = phi i1 [ %cmp
538; DISABLED-CHECK-NEXT: %[[z:.*]] = call i8 @i1toi8(i1 %[[y]])
539; DISABLED-CHECK-NEXT: br label %if.end
540
541; DISABLED-CHECK: if.end:
542; DISABLED-CHECK-NEXT: phi i8
543; DISABLED-CHECK-DAG: [ %[[z]], %[[x]] ]
544; DISABLED-CHECK-DAG: [ 0, %entry ]
545
546define zeroext i1 @test18(i32 %flag, i32 %blksA, i32 %blksB, i32 %nblks) {
547entry:
548  switch i32 %flag, label %if.then3 [
549    i32 0, label %if.then
550    i32 1, label %if.then2
551  ]
552
553if.then:
554  %cmp = icmp uge i32 %blksA, %nblks
555  %frombool1 = zext i1 %cmp to i8
556  br label %if.end
557
558if.then2:
559  %add = add i32 %nblks, %blksB
560  %cmp2 = icmp ule i32 %add, %blksA
561  %frombool3 = zext i1 %cmp2 to i8
562  br label %if.end
563
564if.then3:
565  %add2 = add i32 %nblks, %blksA
566  %cmp3 = icmp ule i32 %add2, %blksA
567  %frombool4 = zext i1 %cmp3 to i8
568  br label %if.end
569
570if.end:
571  %obeys.0 = phi i8 [ %frombool1, %if.then ], [ %frombool3, %if.then2 ], [ %frombool4, %if.then3 ]
572  %tobool4 = icmp ne i8 %obeys.0, 0
573  ret i1 %tobool4
574}
575
576; CHECK-LABEL: test18
577; CHECK: if.end:
578; CHECK-NEXT: %[[x:.*]] = phi i1
579; CHECK-DAG: [ %cmp, %if.then ]
580; CHECK-DAG: [ %cmp2, %if.then2 ]
581; CHECK-DAG: [ %cmp3, %if.then3 ]
582; CHECK-NEXT: zext i1 %[[x]] to i8
583
584; The phi is confusing - both add instructions are used by it, but
585; not on their respective unconditional arcs. It should not be
586; optimized.
587define void @test_pr30292(i1 %cond, i1 %cond2, i32 %a, i32 %b) {
588entry:
589  %add1 = add i32 %a, 1
590  br label %succ
591
592one:
593  br i1 %cond, label %two, label %succ
594
595two:
596  call void @g()
597  %add2 = add i32 %a, 1
598  br label %succ
599
600succ:
601  %p = phi i32 [ 0, %entry ], [ %add1, %one ], [ %add2, %two ]
602  br label %one
603}
604declare void @g()
605
606; CHECK-LABEL: test_pr30292
607; CHECK: phi i32 [ 0, %entry ], [ %add1, %succ ], [ %add2, %two ]
608
609define zeroext i1 @test_pr30244(i1 zeroext %flag, i1 zeroext %flag2, i32 %blksA, i32 %blksB, i32 %nblks) {
610
611entry:
612  %p = alloca i8
613  br i1 %flag, label %if.then, label %if.else
614
615if.then:
616  %cmp = icmp uge i32 %blksA, %nblks
617  %frombool1 = zext i1 %cmp to i8
618  store i8 %frombool1, i8* %p
619  br label %if.end
620
621if.else:
622  br i1 %flag2, label %if.then2, label %if.end
623
624if.then2:
625  %add = add i32 %nblks, %blksB
626  %cmp2 = icmp ule i32 %add, %blksA
627  %frombool3 = zext i1 %cmp2 to i8
628  store i8 %frombool3, i8* %p
629  br label %if.end
630
631if.end:
632  ret i1 true
633}
634
635; CHECK-LABEL: @test_pr30244
636; CHECK: store
637; CHECK-NOT: store
638
639define i32 @test_pr30373a(i1 zeroext %flag, i32 %x, i32 %y) {
640entry:
641  br i1 %flag, label %if.then, label %if.else
642
643if.then:
644  %x0 = call i32 @foo(i32 %x, i32 0) nounwind readnone
645  %y0 = call i32 @foo(i32 %x, i32 1) nounwind readnone
646  %z0 = lshr i32 %y0, 8
647  br label %if.end
648
649if.else:
650  %x1 = call i32 @foo(i32 %y, i32 0) nounwind readnone
651  %y1 = call i32 @foo(i32 %y, i32 1) nounwind readnone
652  %z1 = lshr exact i32 %y1, 8
653  br label %if.end
654
655if.end:
656  %xx = phi i32 [ %x0, %if.then ], [ %x1, %if.else ]
657  %yy = phi i32 [ %z0, %if.then ], [ %z1, %if.else ]
658  %ret = add i32 %xx, %yy
659  ret i32 %ret
660}
661
662; CHECK-LABEL: test_pr30373a
663; CHECK: lshr
664; CHECK-NOT: exact
665; CHECK: }
666
667define i32 @test_pr30373b(i1 zeroext %flag, i32 %x, i32 %y) {
668entry:
669  br i1 %flag, label %if.then, label %if.else
670
671if.then:
672  %x0 = call i32 @foo(i32 %x, i32 0) nounwind readnone
673  %y0 = call i32 @foo(i32 %x, i32 1) nounwind readnone
674  %z0 = lshr exact i32 %y0, 8
675  br label %if.end
676
677if.else:
678  %x1 = call i32 @foo(i32 %y, i32 0) nounwind readnone
679  %y1 = call i32 @foo(i32 %y, i32 1) nounwind readnone
680  %z1 = lshr i32 %y1, 8
681  br label %if.end
682
683if.end:
684  %xx = phi i32 [ %x0, %if.then ], [ %x1, %if.else ]
685  %yy = phi i32 [ %z0, %if.then ], [ %z1, %if.else ]
686  %ret = add i32 %xx, %yy
687  ret i32 %ret
688}
689
690; CHECK-LABEL: test_pr30373b
691; CHECK: lshr
692; CHECK-NOT: exact
693; CHECK: }
694
695; CHECK: !0 = !{!1, !1, i64 0}
696; CHECK: !1 = !{!"float", !2}
697; CHECK: !2 = !{!"an example type tree"}
698