Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / UnreachableEliminate.ll
blobc4602e72ecbce03bc1befe961c69f8ef043ab78b
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
2 ; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1  -S | FileCheck %s
4 define void @test1(i1 %C, ptr %BP) {
5 ; CHECK-LABEL: @test1(
6 ; CHECK-NEXT:  entry:
7 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[C:%.*]], true
8 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
9 ; CHECK-NEXT:    ret void
11 entry:
12   br i1 %C, label %T, label %F
14   store i1 %C, ptr %BP
15   unreachable
17   ret void
20 define void @test2() personality ptr @__gxx_personality_v0 {
21 ; CHECK-LABEL: @test2(
22 ; CHECK-NEXT:  entry:
23 ; CHECK-NEXT:    call void @test2() #[[ATTR4:[0-9]+]]
24 ; CHECK-NEXT:    ret void
26 entry:
27   invoke void @test2( )
28   to label %N unwind label %U
30   %res = landingpad { ptr }
31   cleanup
32   unreachable
34   ret void
37 declare i32 @__gxx_personality_v0(...)
39 define i32 @test3(i32 %v) {
40 ; CHECK-LABEL: @test3(
41 ; CHECK-NEXT:  entry:
42 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[V:%.*]], 2
43 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[COND]], i32 2, i32 1
44 ; CHECK-NEXT:    ret i32 [[SPEC_SELECT]]
46 entry:
47   switch i32 %v, label %default [
48   i32 1, label %U
49   i32 2, label %T
50   ]
51 default:
52   ret i32 1
54   unreachable
56   ret i32 2
60 ;; We can either convert the following control-flow to a select or remove the
61 ;; unreachable control flow because of the undef store of null. Make sure we do
62 ;; the latter.
64 define void @test5(i1 %cond, ptr %ptr) {
65 ; CHECK-LABEL: @test5(
66 ; CHECK-NEXT:  entry:
67 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[COND:%.*]], true
68 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
69 ; CHECK-NEXT:    store i8 2, ptr [[PTR:%.*]], align 8
70 ; CHECK-NEXT:    ret void
72 entry:
73   br i1 %cond, label %bb1, label %bb3
75 bb3:
76   br label %bb2
78 bb1:
79   br label %bb2
81 bb2:
82   %ptr.2 = phi ptr [ %ptr, %bb3 ], [ null, %bb1 ]
83   store i8 2, ptr %ptr.2, align 8
84   ret void
87 declare void @llvm.assume(i1)
88 declare i1 @llvm.type.test(ptr, metadata) nounwind readnone
90 ;; Same as the above test but make sure the unreachable control flow is still
91 ;; removed in the presence of a type test / assume sequence.
93 define void @test5_type_test_assume(i1 %cond, ptr %ptr, ptr %vtable) {
94 ; CHECK-LABEL: @test5_type_test_assume(
95 ; CHECK-NEXT:  entry:
96 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[COND:%.*]], true
97 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
98 ; CHECK-NEXT:    [[P:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE:%.*]], metadata !"foo")
99 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[P]])
100 ; CHECK-NEXT:    store i8 2, ptr [[PTR:%.*]], align 8
101 ; CHECK-NEXT:    ret void
103 entry:
104   br i1 %cond, label %bb1, label %bb3
106 bb3:
107   br label %bb2
109 bb1:
110   br label %bb2
112 bb2:
113   %ptr.2 = phi ptr [ %ptr, %bb3 ], [ null, %bb1 ]
114   %p = call i1 @llvm.type.test(ptr %vtable, metadata !"foo")
115   tail call void @llvm.assume(i1 %p)
116   store i8 2, ptr %ptr.2, align 8
117   ret void
120 define void @test5_no_null_opt(i1 %cond, ptr %ptr) #0 {
121 ; CHECK-LABEL: @test5_no_null_opt(
122 ; CHECK-NEXT:  entry:
123 ; CHECK-NEXT:    [[DOTPTR:%.*]] = select i1 [[COND:%.*]], ptr null, ptr [[PTR:%.*]]
124 ; CHECK-NEXT:    store i8 2, ptr [[DOTPTR]], align 8
125 ; CHECK-NEXT:    ret void
127 entry:
128   br i1 %cond, label %bb1, label %bb3
130 bb3:
131   br label %bb2
133 bb1:
134   br label %bb2
136 bb2:
137   %ptr.2 = phi ptr [ %ptr, %bb3 ], [ null, %bb1 ]
138   store i8 2, ptr %ptr.2, align 8
139   ret void
142 define void @test6(i1 %cond, ptr %ptr) {
143 ; CHECK-LABEL: @test6(
144 ; CHECK-NEXT:  entry:
145 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[COND:%.*]], true
146 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
147 ; CHECK-NEXT:    store i8 2, ptr [[PTR:%.*]], align 8
148 ; CHECK-NEXT:    ret void
150 entry:
151   br i1 %cond, label %bb1, label %bb2
153 bb1:
154   br label %bb2
156 bb2:
157   %ptr.2 = phi ptr [ %ptr, %entry ], [ null, %bb1 ]
158   store i8 2, ptr %ptr.2, align 8
159   ret void
162 define void @test6_no_null_opt(i1 %cond, ptr %ptr) #0 {
163 ; CHECK-LABEL: @test6_no_null_opt(
164 ; CHECK-NEXT:  entry:
165 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[COND:%.*]], ptr null, ptr [[PTR:%.*]]
166 ; CHECK-NEXT:    store i8 2, ptr [[SPEC_SELECT]], align 8
167 ; CHECK-NEXT:    ret void
169 entry:
170   br i1 %cond, label %bb1, label %bb2
172 bb1:
173   br label %bb2
175 bb2:
176   %ptr.2 = phi ptr [ %ptr, %entry ], [ null, %bb1 ]
177   store i8 2, ptr %ptr.2, align 8
178   ret void
182 define i32 @test7(i1 %X) {
183 ; CHECK-LABEL: @test7(
184 ; CHECK-NEXT:  entry:
185 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
186 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
187 ; CHECK-NEXT:    ret i32 0
189 entry:
190   br i1 %X, label %if, label %else
193   call void undef()
194   br label %else
196 else:
197   %phi = phi i32 [ 0, %entry ], [ 1, %if ]
198   ret i32 %phi
201 define void @test8(i1 %X, ptr %Y) {
202 ; CHECK-LABEL: @test8(
203 ; CHECK-NEXT:  entry:
204 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
205 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
206 ; CHECK-NEXT:    call void [[Y:%.*]]()
207 ; CHECK-NEXT:    ret void
209 entry:
210   br i1 %X, label %if, label %else
213   br label %else
215 else:
216   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
217   call void %phi()
218   ret void
221 define void @test8_no_null_opt(i1 %X, ptr %Y) #0 {
222 ; CHECK-LABEL: @test8_no_null_opt(
223 ; CHECK-NEXT:  entry:
224 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
225 ; CHECK-NEXT:    call void [[SPEC_SELECT]]()
226 ; CHECK-NEXT:    ret void
228 entry:
229   br i1 %X, label %if, label %else
232   br label %else
234 else:
235   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
236   call void %phi()
237   ret void
240 declare ptr @fn_nonnull_noundef_arg(ptr nonnull noundef %p)
241 declare ptr @fn_nonnull_deref_arg(ptr nonnull dereferenceable(4) %p)
242 declare ptr @fn_nonnull_deref_or_null_arg(ptr nonnull dereferenceable_or_null(4) %p)
243 declare ptr @fn_nonnull_arg(ptr nonnull %p)
244 declare ptr @fn_noundef_arg(ptr noundef %p)
245 declare ptr @fn_ptr_arg(ptr)
246 declare ptr @fn_ptr_arg_nounwind_willreturn(ptr) nounwind willreturn
248 define void @test9(i1 %X, ptr %Y) {
249 ; CHECK-LABEL: @test9(
250 ; CHECK-NEXT:  entry:
251 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
252 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
253 ; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[Y:%.*]])
254 ; CHECK-NEXT:    ret void
256 entry:
257   br i1 %X, label %if, label %else
260   br label %else
262 else:
263   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
264   call ptr @fn_nonnull_noundef_arg(ptr %phi)
265   ret void
268 ; Optimizing this code should produce assume.
269 define void @test9_deref(i1 %X, ptr %Y) {
270 ; CHECK-LABEL: @test9_deref(
271 ; CHECK-NEXT:  entry:
272 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
273 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
274 ; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @fn_nonnull_deref_arg(ptr [[Y:%.*]])
275 ; CHECK-NEXT:    ret void
277 entry:
278   br i1 %X, label %if, label %else
281   br label %else
283 else:
284   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
285   call ptr @fn_nonnull_deref_arg(ptr %phi)
286   ret void
289 ; Optimizing this code should produce assume.
290 define void @test9_deref_or_null(i1 %X, ptr %Y) {
291 ; CHECK-LABEL: @test9_deref_or_null(
292 ; CHECK-NEXT:  entry:
293 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
294 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
295 ; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @fn_nonnull_deref_or_null_arg(ptr [[Y:%.*]])
296 ; CHECK-NEXT:    ret void
298 entry:
299   br i1 %X, label %if, label %else
302   br label %else
304 else:
305   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
306   call ptr @fn_nonnull_deref_or_null_arg(ptr %phi)
307   ret void
310 define void @test9_undef(i1 %X, ptr %Y) {
311 ; CHECK-LABEL: @test9_undef(
312 ; CHECK-NEXT:  entry:
313 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_noundef_arg(ptr [[Y:%.*]])
314 ; CHECK-NEXT:    ret void
316 entry:
317   br i1 %X, label %if, label %else
320   br label %else
322 else:
323   %phi = phi ptr [ %Y, %entry ], [ undef, %if ]
324   call ptr @fn_noundef_arg(ptr %phi)
325   ret void
328 define void @test9_undef_null_defined(i1 %X, ptr %Y) #0 {
329 ; CHECK-LABEL: @test9_undef_null_defined(
330 ; CHECK-NEXT:  entry:
331 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_noundef_arg(ptr [[Y:%.*]])
332 ; CHECK-NEXT:    ret void
334 entry:
335   br i1 %X, label %if, label %else
338   br label %else
340 else:
341   %phi = phi ptr [ %Y, %entry ], [ undef, %if ]
342   call ptr @fn_noundef_arg(ptr %phi)
343   ret void
346 define void @test9_null_callsite(i1 %X, ptr %Y) {
347 ; CHECK-LABEL: @test9_null_callsite(
348 ; CHECK-NEXT:  entry:
349 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
350 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
351 ; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @fn_nonnull_arg(ptr noundef nonnull [[Y:%.*]])
352 ; CHECK-NEXT:    ret void
354 entry:
355   br i1 %X, label %if, label %else
358   br label %else
360 else:
361   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
362   call ptr @fn_nonnull_arg(ptr nonnull noundef %phi)
363   ret void
366 define void @test9_gep_mismatch(i1 %X, ptr %Y,  ptr %P) {
367 ; CHECK-LABEL: @test9_gep_mismatch(
368 ; CHECK-NEXT:  entry:
369 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
370 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[P:%.*]])
371 ; CHECK-NEXT:    ret void
373 entry:
374   br i1 %X, label %if, label %else
377   br label %else
379 else:
380   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
381   call ptr @fn_nonnull_noundef_arg(ptr %P)
382   ret void
385 define void @test9_gep_zero(i1 %X, ptr %Y) {
386 ; CHECK-LABEL: @test9_gep_zero(
387 ; CHECK-NEXT:  entry:
388 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
389 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
390 ; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[Y:%.*]])
391 ; CHECK-NEXT:    ret void
393 entry:
394   br i1 %X, label %if, label %else
397   br label %else
399 else:
400   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
401   call ptr @fn_nonnull_noundef_arg(ptr %phi)
402   ret void
405 define void @test9_gep_bitcast(i1 %X, ptr %Y) {
406 ; CHECK-LABEL: @test9_gep_bitcast(
407 ; CHECK-NEXT:  entry:
408 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
409 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
410 ; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[Y:%.*]])
411 ; CHECK-NEXT:    ret void
413 entry:
414   br i1 %X, label %if, label %else
417   br label %else
419 else:
420   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
421   call ptr @fn_nonnull_noundef_arg(ptr %phi)
422   ret void
425 define void @test9_gep_nonzero(i1 %X, ptr %Y) {
426 ; CHECK-LABEL: @test9_gep_nonzero(
427 ; CHECK-NEXT:  entry:
428 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
429 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[SPEC_SELECT]], i64 12
430 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
431 ; CHECK-NEXT:    ret void
433 entry:
434   br i1 %X, label %if, label %else
437   br label %else
439 else:
440   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
441   %gep = getelementptr i8, ptr %phi, i64 12
442   call ptr @fn_nonnull_noundef_arg(ptr %gep)
443   ret void
446 define void @test9_gep_inbounds_nonzero(i1 %X, ptr %Y) {
447 ; CHECK-LABEL: @test9_gep_inbounds_nonzero(
448 ; CHECK-NEXT:  entry:
449 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
450 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
451 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[Y:%.*]], i64 12
452 ; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
453 ; CHECK-NEXT:    ret void
455 entry:
456   br i1 %X, label %if, label %else
459   br label %else
461 else:
462   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
463   %gep = getelementptr inbounds i8, ptr %phi, i64 12
464   call ptr @fn_nonnull_noundef_arg(ptr %gep)
465   ret void
468 define void @test9_gep_inbounds_nonzero_null_defined(i1 %X, ptr %Y) #0 {
469 ; CHECK-LABEL: @test9_gep_inbounds_nonzero_null_defined(
470 ; CHECK-NEXT:  entry:
471 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
472 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[SPEC_SELECT]], i64 12
473 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
474 ; CHECK-NEXT:    ret void
476 entry:
477   br i1 %X, label %if, label %else
480   br label %else
482 else:
483   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
484   %gep = getelementptr inbounds i8, ptr %phi, i64 12
485   call ptr @fn_nonnull_noundef_arg(ptr %gep)
486   ret void
489 define void @test9_gep_inbounds_unknown_null(i1 %X, ptr %Y, i64 %I) {
490 ; CHECK-LABEL: @test9_gep_inbounds_unknown_null(
491 ; CHECK-NEXT:  entry:
492 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
493 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
494 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[Y:%.*]], i64 [[I:%.*]]
495 ; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
496 ; CHECK-NEXT:    ret void
498 entry:
499   br i1 %X, label %if, label %else
502   br label %else
504 else:
505   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
506   %gep = getelementptr inbounds i8, ptr %phi, i64 %I
507   call ptr @fn_nonnull_noundef_arg(ptr %gep)
508   ret void
511 define void @test9_gep_inbounds_unknown_null_defined(i1 %X, ptr %Y, i64 %I) #0 {
512 ; CHECK-LABEL: @test9_gep_inbounds_unknown_null_defined(
513 ; CHECK-NEXT:  entry:
514 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
515 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[SPEC_SELECT]], i64 [[I:%.*]]
516 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
517 ; CHECK-NEXT:    ret void
519 entry:
520   br i1 %X, label %if, label %else
523   br label %else
525 else:
526   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
527   %gep = getelementptr inbounds i8, ptr %phi, i64 %I
528   call ptr @fn_nonnull_noundef_arg(ptr %gep)
529   ret void
532 define void @test9_gep_inbounds_unknown_null_call_noundef(i1 %X, ptr %Y, i64 %I) {
533 ; CHECK-LABEL: @test9_gep_inbounds_unknown_null_call_noundef(
534 ; CHECK-NEXT:  entry:
535 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
536 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[SPEC_SELECT]], i64 [[I:%.*]]
537 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_noundef_arg(ptr [[GEP]])
538 ; CHECK-NEXT:    ret void
540 entry:
541   br i1 %X, label %if, label %else
544   br label %else
546 else:
547   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
548   %gep = getelementptr inbounds i8, ptr %phi, i64 %I
549   call ptr @fn_noundef_arg(ptr %gep)
550   ret void
553 define void @test9_gep_unknown_null(i1 %X, ptr %Y, i64 %I) {
554 ; CHECK-LABEL: @test9_gep_unknown_null(
555 ; CHECK-NEXT:  entry:
556 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
557 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[SPEC_SELECT]], i64 [[I:%.*]]
558 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
559 ; CHECK-NEXT:    ret void
561 entry:
562   br i1 %X, label %if, label %else
565   br label %else
567 else:
568   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
569   %gep = getelementptr i8, ptr %phi, i64 %I
570   call ptr @fn_nonnull_noundef_arg(ptr %gep)
571   ret void
574 define void @test9_gep_unknown_undef(i1 %X, ptr %Y, i64 %I) {
575 ; CHECK-LABEL: @test9_gep_unknown_undef(
576 ; CHECK-NEXT:  entry:
577 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[Y:%.*]], i64 [[I:%.*]]
578 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_noundef_arg(ptr [[GEP]])
579 ; CHECK-NEXT:    ret void
581 entry:
582   br i1 %X, label %if, label %else
585   br label %else
587 else:
588   %phi = phi ptr [ %Y, %entry ], [ undef, %if ]
589   %gep = getelementptr i8, ptr %phi, i64 %I
590   call ptr @fn_noundef_arg(ptr %gep)
591   ret void
594 define void @test9_missing_noundef(i1 %X, ptr %Y) {
595 ; CHECK-LABEL: @test9_missing_noundef(
596 ; CHECK-NEXT:  entry:
597 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
598 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_arg(ptr [[SPEC_SELECT]])
599 ; CHECK-NEXT:    ret void
601 entry:
602   br i1 %X, label %if, label %else
605   br label %else
607 else:
608   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
609   call ptr @fn_nonnull_arg(ptr %phi)
610   ret void
613 define void @test9_null_defined(i1 %X, ptr %Y) #0 {
614 ; CHECK-LABEL: @test9_null_defined(
615 ; CHECK-NEXT:  entry:
616 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
617 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[SPEC_SELECT]])
618 ; CHECK-NEXT:    ret void
620 entry:
621   br i1 %X, label %if, label %else
624   br label %else
626 else:
627   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
628   call ptr @fn_nonnull_noundef_arg(ptr %phi)
629   ret void
632 define i32 @test_assume_false(i32 %cond) {
633 ; CHECK-LABEL: @test_assume_false(
634 ; CHECK-NEXT:  entry:
635 ; CHECK-NEXT:    switch i32 [[COND:%.*]], label [[DEFAULT:%.*]] [
636 ; CHECK-NEXT:      i32 0, label [[EXIT:%.*]]
637 ; CHECK-NEXT:      i32 1, label [[CASE1:%.*]]
638 ; CHECK-NEXT:      i32 2, label [[CASE2:%.*]]
639 ; CHECK-NEXT:    ]
640 ; CHECK:       case1:
641 ; CHECK-NEXT:    br label [[EXIT]]
642 ; CHECK:       case2:
643 ; CHECK-NEXT:    br label [[EXIT]]
644 ; CHECK:       default:
645 ; CHECK-NEXT:    unreachable
646 ; CHECK:       exit:
647 ; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ 2, [[CASE1]] ], [ 3, [[CASE2]] ], [ 1, [[ENTRY:%.*]] ]
648 ; CHECK-NEXT:    call void @llvm.assume(i1 true)
649 ; CHECK-NEXT:    ret i32 [[RES]]
651 entry:
652   switch i32 %cond, label %default [
653   i32 0, label %case0
654   i32 1, label %case1
655   i32 2, label %case2
656   ]
658 case0:
659   br label %exit
661 case1:
662   br label %exit
664 case2:
665   br label %exit
667 default:
668   br label %exit
670 exit:
671   %bool = phi i1 [ false, %default ], [ true, %case0 ], [ true, %case1 ], [ true, %case2 ]
672   %res = phi i32 [ 0, %default ], [ 1, %case0 ], [ 2, %case1 ], [ 3, %case2 ]
673   call void @llvm.assume(i1 %bool)
674   ret i32 %res
677 define i32 @test_assume_undef(i32 %cond) {
678 ; CHECK-LABEL: @test_assume_undef(
679 ; CHECK-NEXT:  entry:
680 ; CHECK-NEXT:    switch i32 [[COND:%.*]], label [[DEFAULT:%.*]] [
681 ; CHECK-NEXT:      i32 0, label [[EXIT:%.*]]
682 ; CHECK-NEXT:      i32 1, label [[CASE1:%.*]]
683 ; CHECK-NEXT:      i32 2, label [[CASE2:%.*]]
684 ; CHECK-NEXT:    ]
685 ; CHECK:       case1:
686 ; CHECK-NEXT:    br label [[EXIT]]
687 ; CHECK:       case2:
688 ; CHECK-NEXT:    br label [[EXIT]]
689 ; CHECK:       default:
690 ; CHECK-NEXT:    unreachable
691 ; CHECK:       exit:
692 ; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ 2, [[CASE1]] ], [ 3, [[CASE2]] ], [ 1, [[ENTRY:%.*]] ]
693 ; CHECK-NEXT:    call void @llvm.assume(i1 true)
694 ; CHECK-NEXT:    ret i32 [[RES]]
696 entry:
697   switch i32 %cond, label %default [
698   i32 0, label %case0
699   i32 1, label %case1
700   i32 2, label %case2
701   ]
703 case0:
704   br label %exit
706 case1:
707   br label %exit
709 case2:
710   br label %exit
712 default:
713   br label %exit
715 exit:
716   %bool = phi i1 [ undef, %default ], [ true, %case0 ], [ true, %case1 ], [ true, %case2 ]
717   %res = phi i32 [ 0, %default ], [ 1, %case0 ], [ 2, %case1 ], [ 3, %case2 ]
718   call void @llvm.assume(i1 %bool)
719   ret i32 %res
722 define i32 @test_assume_var(i32 %cond, i1 %var) {
723 ; CHECK-LABEL: @test_assume_var(
724 ; CHECK-NEXT:  entry:
725 ; CHECK-NEXT:    switch i32 [[COND:%.*]], label [[DEFAULT:%.*]] [
726 ; CHECK-NEXT:      i32 0, label [[EXIT:%.*]]
727 ; CHECK-NEXT:      i32 1, label [[CASE1:%.*]]
728 ; CHECK-NEXT:      i32 2, label [[CASE2:%.*]]
729 ; CHECK-NEXT:    ]
730 ; CHECK:       case1:
731 ; CHECK-NEXT:    br label [[EXIT]]
732 ; CHECK:       case2:
733 ; CHECK-NEXT:    br label [[EXIT]]
734 ; CHECK:       default:
735 ; CHECK-NEXT:    br label [[EXIT]]
736 ; CHECK:       exit:
737 ; CHECK-NEXT:    [[BOOL:%.*]] = phi i1 [ [[VAR:%.*]], [[DEFAULT]] ], [ true, [[CASE1]] ], [ true, [[CASE2]] ], [ true, [[ENTRY:%.*]] ]
738 ; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ 0, [[DEFAULT]] ], [ 2, [[CASE1]] ], [ 3, [[CASE2]] ], [ 1, [[ENTRY]] ]
739 ; CHECK-NEXT:    call void @llvm.assume(i1 [[BOOL]])
740 ; CHECK-NEXT:    ret i32 [[RES]]
742 entry:
743   switch i32 %cond, label %default [
744   i32 0, label %case0
745   i32 1, label %case1
746   i32 2, label %case2
747   ]
749 case0:
750   br label %exit
752 case1:
753   br label %exit
755 case2:
756   br label %exit
758 default:
759   br label %exit
761 exit:
762   %bool = phi i1 [ %var, %default ], [ true, %case0 ], [ true, %case1 ], [ true, %case2 ]
763   %res = phi i32 [ 0, %default ], [ 1, %case0 ], [ 2, %case1 ], [ 3, %case2 ]
764   call void @llvm.assume(i1 %bool)
765   ret i32 %res
768 define i32 @test_assume_bundle_nonnull(i32 %cond, ptr nonnull %p) {
769 ; CHECK-LABEL: @test_assume_bundle_nonnull(
770 ; CHECK-NEXT:  entry:
771 ; CHECK-NEXT:    switch i32 [[COND:%.*]], label [[DEFAULT:%.*]] [
772 ; CHECK-NEXT:      i32 0, label [[EXIT:%.*]]
773 ; CHECK-NEXT:      i32 1, label [[CASE1:%.*]]
774 ; CHECK-NEXT:      i32 2, label [[CASE2:%.*]]
775 ; CHECK-NEXT:    ]
776 ; CHECK:       case1:
777 ; CHECK-NEXT:    br label [[EXIT]]
778 ; CHECK:       case2:
779 ; CHECK-NEXT:    br label [[EXIT]]
780 ; CHECK:       default:
781 ; CHECK-NEXT:    br label [[EXIT]]
782 ; CHECK:       exit:
783 ; CHECK-NEXT:    [[PTR:%.*]] = phi ptr [ null, [[DEFAULT]] ], [ [[P:%.*]], [[CASE1]] ], [ [[P]], [[CASE2]] ], [ [[P]], [[ENTRY:%.*]] ]
784 ; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ 0, [[DEFAULT]] ], [ 2, [[CASE1]] ], [ 3, [[CASE2]] ], [ 1, [[ENTRY]] ]
785 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[PTR]]) ]
786 ; CHECK-NEXT:    ret i32 [[RES]]
788 entry:
789   switch i32 %cond, label %default [
790   i32 0, label %case0
791   i32 1, label %case1
792   i32 2, label %case2
793   ]
795 case0:
796   br label %exit
798 case1:
799   br label %exit
801 case2:
802   br label %exit
804 default:
805   br label %exit
807 exit:
808   %ptr = phi ptr [ null, %default ], [ %p, %case0 ], [ %p, %case1 ], [ %p, %case2 ]
809   %res = phi i32 [ 0, %default ], [ 1, %case0 ], [ 2, %case1 ], [ 3, %case2 ]
810   call void @llvm.assume(i1 true) [ "nonnull"(ptr %ptr) ]
811   ret i32 %res
814 define i32 @test_assume_bundle_align(i32 %cond, ptr nonnull %p) {
815 ; CHECK-LABEL: @test_assume_bundle_align(
816 ; CHECK-NEXT:  entry:
817 ; CHECK-NEXT:    switch i32 [[COND:%.*]], label [[DEFAULT:%.*]] [
818 ; CHECK-NEXT:      i32 0, label [[EXIT:%.*]]
819 ; CHECK-NEXT:      i32 1, label [[CASE1:%.*]]
820 ; CHECK-NEXT:      i32 2, label [[CASE2:%.*]]
821 ; CHECK-NEXT:    ]
822 ; CHECK:       case1:
823 ; CHECK-NEXT:    br label [[EXIT]]
824 ; CHECK:       case2:
825 ; CHECK-NEXT:    br label [[EXIT]]
826 ; CHECK:       default:
827 ; CHECK-NEXT:    br label [[EXIT]]
828 ; CHECK:       exit:
829 ; CHECK-NEXT:    [[PTR:%.*]] = phi ptr [ null, [[DEFAULT]] ], [ [[P:%.*]], [[CASE1]] ], [ [[P]], [[CASE2]] ], [ [[P]], [[ENTRY:%.*]] ]
830 ; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ 0, [[DEFAULT]] ], [ 2, [[CASE1]] ], [ 3, [[CASE2]] ], [ 1, [[ENTRY]] ]
831 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[PTR]], i32 8) ]
832 ; CHECK-NEXT:    ret i32 [[RES]]
834 entry:
835   switch i32 %cond, label %default [
836   i32 0, label %case0
837   i32 1, label %case1
838   i32 2, label %case2
839   ]
841 case0:
842   br label %exit
844 case1:
845   br label %exit
847 case2:
848   br label %exit
850 default:
851   br label %exit
853 exit:
854   %ptr = phi ptr [ null, %default ], [ %p, %case0 ], [ %p, %case1 ], [ %p, %case2 ]
855   %res = phi i32 [ 0, %default ], [ 1, %case0 ], [ 2, %case1 ], [ 3, %case2 ]
856   call void @llvm.assume(i1 true) [ "align"(ptr %ptr, i32 8) ]
857   ret i32 %res
860 ; From bb to bb5 is UB.
861 define i32 @test9_null_user_order_1(ptr %arg, i1 %arg1, ptr %arg2) {
862 ; CHECK-LABEL: @test9_null_user_order_1(
863 ; CHECK-NEXT:  bb:
864 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
865 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
866 ; CHECK-NEXT:    [[I:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
867 ; CHECK-NEXT:    [[I4:%.*]] = getelementptr inbounds i8, ptr [[I]], i64 1
868 ; CHECK-NEXT:    store ptr [[I4]], ptr [[ARG]], align 8
869 ; CHECK-NEXT:    [[I7:%.*]] = load i32, ptr [[I]], align 4
870 ; CHECK-NEXT:    [[I8:%.*]] = icmp ne ptr [[I]], [[ARG2:%.*]]
871 ; CHECK-NEXT:    call void @fn_ptr_arg(i1 [[I8]])
872 ; CHECK-NEXT:    ret i32 [[I7]]
875   br i1 %arg1, label %bb5, label %bb3
877 bb3:                                              ; preds = %bb
878   %i = load ptr, ptr %arg, align 8
879   %i4 = getelementptr inbounds i8, ptr %i, i64 1
880   store ptr %i4, ptr %arg, align 8
881   br label %bb5
883 bb5:                                              ; preds = %bb3, %bb
884   %i6 = phi ptr [ %i, %bb3 ], [ null, %bb ]
885   %i7 = load i32, ptr %i6, align 4
886   %i8 = icmp ne ptr %i6, %arg2
887   call void @fn_ptr_arg(i1 %i8)
888   ret i32 %i7
891 define i32 @test9_null_user_order_2(ptr %arg, i1 %arg1, ptr %arg2) {
892 ; CHECK-LABEL: @test9_null_user_order_2(
893 ; CHECK-NEXT:  bb:
894 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
895 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
896 ; CHECK-NEXT:    [[I:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
897 ; CHECK-NEXT:    [[I4:%.*]] = getelementptr inbounds i8, ptr [[I]], i64 1
898 ; CHECK-NEXT:    store ptr [[I4]], ptr [[ARG]], align 8
899 ; CHECK-NEXT:    [[I8:%.*]] = icmp ne ptr [[I]], [[ARG2:%.*]]
900 ; CHECK-NEXT:    call void @fn_ptr_arg_nounwind_willreturn(i1 [[I8]])
901 ; CHECK-NEXT:    [[I7:%.*]] = load i32, ptr [[I]], align 4
902 ; CHECK-NEXT:    ret i32 [[I7]]
905   br i1 %arg1, label %bb5, label %bb3
907 bb3:                                              ; preds = %bb
908   %i = load ptr, ptr %arg, align 8
909   %i4 = getelementptr inbounds i8, ptr %i, i64 1
910   store ptr %i4, ptr %arg, align 8
911   br label %bb5
913 bb5:                                              ; preds = %bb3, %bb
914   %i6 = phi ptr [ %i, %bb3 ], [ null, %bb ]
915   %i8 = icmp ne ptr %i6, %arg2
916   call void @fn_ptr_arg_nounwind_willreturn(i1 %i8)
917   %i7 = load i32, ptr %i6, align 4
918   ret i32 %i7
921 attributes #0 = { null_pointer_is_valid }
923 ; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
924 ; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
925 ; CHECK: attributes #[[ATTR2:[0-9]+]] = { null_pointer_is_valid }
926 ; CHECK: attributes #[[ATTR3:[0-9]+]] = { nounwind willreturn }
927 ; CHECK: attributes #[[ATTR4]] = { nounwind }