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) {
7 ; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[C:%.*]], true
8 ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
12 br i1 %C, label %T, label %F
20 define void @test2() personality ptr @__gxx_personality_v0 {
21 ; CHECK-LABEL: @test2(
23 ; CHECK-NEXT: call void @test2() #[[ATTR4:[0-9]+]]
24 ; CHECK-NEXT: ret void
28 to label %N unwind label %U
30 %res = landingpad { ptr }
37 declare i32 @__gxx_personality_v0(...)
39 define i32 @test3(i32 %v) {
40 ; CHECK-LABEL: @test3(
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]]
47 switch i32 %v, label %default [
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
64 define void @test5(i1 %cond, ptr %ptr) {
65 ; CHECK-LABEL: @test5(
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
73 br i1 %cond, label %bb1, label %bb3
82 %ptr.2 = phi ptr [ %ptr, %bb3 ], [ null, %bb1 ]
83 store i8 2, ptr %ptr.2, align 8
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(
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
104 br i1 %cond, label %bb1, label %bb3
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
120 define void @test5_no_null_opt(i1 %cond, ptr %ptr) #0 {
121 ; CHECK-LABEL: @test5_no_null_opt(
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
128 br i1 %cond, label %bb1, label %bb3
137 %ptr.2 = phi ptr [ %ptr, %bb3 ], [ null, %bb1 ]
138 store i8 2, ptr %ptr.2, align 8
142 define void @test6(i1 %cond, ptr %ptr) {
143 ; CHECK-LABEL: @test6(
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
151 br i1 %cond, label %bb1, label %bb2
157 %ptr.2 = phi ptr [ %ptr, %entry ], [ null, %bb1 ]
158 store i8 2, ptr %ptr.2, align 8
162 define void @test6_no_null_opt(i1 %cond, ptr %ptr) #0 {
163 ; CHECK-LABEL: @test6_no_null_opt(
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
170 br i1 %cond, label %bb1, label %bb2
176 %ptr.2 = phi ptr [ %ptr, %entry ], [ null, %bb1 ]
177 store i8 2, ptr %ptr.2, align 8
182 define i32 @test7(i1 %X) {
183 ; CHECK-LABEL: @test7(
185 ; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true
186 ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
187 ; CHECK-NEXT: ret i32 0
190 br i1 %X, label %if, label %else
197 %phi = phi i32 [ 0, %entry ], [ 1, %if ]
201 define void @test8(i1 %X, ptr %Y) {
202 ; CHECK-LABEL: @test8(
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
210 br i1 %X, label %if, label %else
216 %phi = phi ptr [ %Y, %entry ], [ null, %if ]
221 define void @test8_no_null_opt(i1 %X, ptr %Y) #0 {
222 ; CHECK-LABEL: @test8_no_null_opt(
224 ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
225 ; CHECK-NEXT: call void [[SPEC_SELECT]]()
226 ; CHECK-NEXT: ret void
229 br i1 %X, label %if, label %else
235 %phi = phi ptr [ %Y, %entry ], [ null, %if ]
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(
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
257 br i1 %X, label %if, label %else
263 %phi = phi ptr [ %Y, %entry ], [ null, %if ]
264 call ptr @fn_nonnull_noundef_arg(ptr %phi)
268 ; Optimizing this code should produce assume.
269 define void @test9_deref(i1 %X, ptr %Y) {
270 ; CHECK-LABEL: @test9_deref(
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
278 br i1 %X, label %if, label %else
284 %phi = phi ptr [ %Y, %entry ], [ null, %if ]
285 call ptr @fn_nonnull_deref_arg(ptr %phi)
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(
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
299 br i1 %X, label %if, label %else
305 %phi = phi ptr [ %Y, %entry ], [ null, %if ]
306 call ptr @fn_nonnull_deref_or_null_arg(ptr %phi)
310 define void @test9_undef(i1 %X, ptr %Y) {
311 ; CHECK-LABEL: @test9_undef(
313 ; CHECK-NEXT: [[TMP0:%.*]] = call ptr @fn_noundef_arg(ptr [[Y:%.*]])
314 ; CHECK-NEXT: ret void
317 br i1 %X, label %if, label %else
323 %phi = phi ptr [ %Y, %entry ], [ undef, %if ]
324 call ptr @fn_noundef_arg(ptr %phi)
328 define void @test9_undef_null_defined(i1 %X, ptr %Y) #0 {
329 ; CHECK-LABEL: @test9_undef_null_defined(
331 ; CHECK-NEXT: [[TMP0:%.*]] = call ptr @fn_noundef_arg(ptr [[Y:%.*]])
332 ; CHECK-NEXT: ret void
335 br i1 %X, label %if, label %else
341 %phi = phi ptr [ %Y, %entry ], [ undef, %if ]
342 call ptr @fn_noundef_arg(ptr %phi)
346 define void @test9_null_callsite(i1 %X, ptr %Y) {
347 ; CHECK-LABEL: @test9_null_callsite(
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
355 br i1 %X, label %if, label %else
361 %phi = phi ptr [ %Y, %entry ], [ null, %if ]
362 call ptr @fn_nonnull_arg(ptr nonnull noundef %phi)
366 define void @test9_gep_mismatch(i1 %X, ptr %Y, ptr %P) {
367 ; CHECK-LABEL: @test9_gep_mismatch(
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
374 br i1 %X, label %if, label %else
380 %phi = phi ptr [ %Y, %entry ], [ null, %if ]
381 call ptr @fn_nonnull_noundef_arg(ptr %P)
385 define void @test9_gep_zero(i1 %X, ptr %Y) {
386 ; CHECK-LABEL: @test9_gep_zero(
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
394 br i1 %X, label %if, label %else
400 %phi = phi ptr [ %Y, %entry ], [ null, %if ]
401 call ptr @fn_nonnull_noundef_arg(ptr %phi)
405 define void @test9_gep_bitcast(i1 %X, ptr %Y) {
406 ; CHECK-LABEL: @test9_gep_bitcast(
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
414 br i1 %X, label %if, label %else
420 %phi = phi ptr [ %Y, %entry ], [ null, %if ]
421 call ptr @fn_nonnull_noundef_arg(ptr %phi)
425 define void @test9_gep_nonzero(i1 %X, ptr %Y) {
426 ; CHECK-LABEL: @test9_gep_nonzero(
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
434 br i1 %X, label %if, label %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)
446 define void @test9_gep_inbounds_nonzero(i1 %X, ptr %Y) {
447 ; CHECK-LABEL: @test9_gep_inbounds_nonzero(
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
456 br i1 %X, label %if, label %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)
468 define void @test9_gep_inbounds_nonzero_null_defined(i1 %X, ptr %Y) #0 {
469 ; CHECK-LABEL: @test9_gep_inbounds_nonzero_null_defined(
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
477 br i1 %X, label %if, label %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)
489 define void @test9_gep_inbounds_unknown_null(i1 %X, ptr %Y, i64 %I) {
490 ; CHECK-LABEL: @test9_gep_inbounds_unknown_null(
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
499 br i1 %X, label %if, label %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)
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(
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
520 br i1 %X, label %if, label %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)
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(
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
541 br i1 %X, label %if, label %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)
553 define void @test9_gep_unknown_null(i1 %X, ptr %Y, i64 %I) {
554 ; CHECK-LABEL: @test9_gep_unknown_null(
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
562 br i1 %X, label %if, label %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)
574 define void @test9_gep_unknown_undef(i1 %X, ptr %Y, i64 %I) {
575 ; CHECK-LABEL: @test9_gep_unknown_undef(
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
582 br i1 %X, label %if, label %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)
594 define void @test9_missing_noundef(i1 %X, ptr %Y) {
595 ; CHECK-LABEL: @test9_missing_noundef(
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
602 br i1 %X, label %if, label %else
608 %phi = phi ptr [ %Y, %entry ], [ null, %if ]
609 call ptr @fn_nonnull_arg(ptr %phi)
613 define void @test9_null_defined(i1 %X, ptr %Y) #0 {
614 ; CHECK-LABEL: @test9_null_defined(
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
621 br i1 %X, label %if, label %else
627 %phi = phi ptr [ %Y, %entry ], [ null, %if ]
628 call ptr @fn_nonnull_noundef_arg(ptr %phi)
632 define i32 @test_assume_false(i32 %cond) {
633 ; CHECK-LABEL: @test_assume_false(
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:%.*]]
641 ; CHECK-NEXT: br label [[EXIT]]
643 ; CHECK-NEXT: br label [[EXIT]]
645 ; CHECK-NEXT: unreachable
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]]
652 switch i32 %cond, label %default [
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)
677 define i32 @test_assume_undef(i32 %cond) {
678 ; CHECK-LABEL: @test_assume_undef(
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:%.*]]
686 ; CHECK-NEXT: br label [[EXIT]]
688 ; CHECK-NEXT: br label [[EXIT]]
690 ; CHECK-NEXT: unreachable
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]]
697 switch i32 %cond, label %default [
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)
722 define i32 @test_assume_var(i32 %cond, i1 %var) {
723 ; CHECK-LABEL: @test_assume_var(
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:%.*]]
731 ; CHECK-NEXT: br label [[EXIT]]
733 ; CHECK-NEXT: br label [[EXIT]]
735 ; CHECK-NEXT: br label [[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]]
743 switch i32 %cond, label %default [
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)
768 define i32 @test_assume_bundle_nonnull(i32 %cond, ptr nonnull %p) {
769 ; CHECK-LABEL: @test_assume_bundle_nonnull(
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:%.*]]
777 ; CHECK-NEXT: br label [[EXIT]]
779 ; CHECK-NEXT: br label [[EXIT]]
781 ; CHECK-NEXT: br label [[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]]
789 switch i32 %cond, label %default [
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) ]
814 define i32 @test_assume_bundle_align(i32 %cond, ptr nonnull %p) {
815 ; CHECK-LABEL: @test_assume_bundle_align(
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:%.*]]
823 ; CHECK-NEXT: br label [[EXIT]]
825 ; CHECK-NEXT: br label [[EXIT]]
827 ; CHECK-NEXT: br label [[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]]
835 switch i32 %cond, label %default [
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) ]
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(
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
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
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)
891 define i32 @test9_null_user_order_2(ptr %arg, i1 %arg1, ptr %arg2) {
892 ; CHECK-LABEL: @test9_null_user_order_2(
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
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
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
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 }