; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals ; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" ; Test cases specifically designed for the "undefined behavior" abstract function attribute. ; We want to verify that whenever undefined behavior is assumed, the code becomes unreachable. ; We use FIXME's to indicate problems and missing attributes. ; -- Load tests -- define void @load_wholly_unreachable() { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@load_wholly_unreachable ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: unreachable ; %a = load i32, i32* null ret void } define void @loads_wholly_unreachable() { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@loads_wholly_unreachable ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: unreachable ; %a = load i32, i32* null %b = load i32, i32* null ret void } define void @load_single_bb_unreachable(i1 %cond) { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@load_single_bb_unreachable ; CHECK-SAME: (i1 [[COND:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] ; CHECK: t: ; CHECK-NEXT: unreachable ; CHECK: e: ; CHECK-NEXT: ret void ; br i1 %cond, label %t, label %e t: %b = load i32, i32* null br label %e e: ret void } ; Note that while the load is removed (because it's unused), the block ; is not changed to unreachable define void @load_null_pointer_is_defined() null_pointer_is_valid { ; CHECK: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@load_null_pointer_is_defined ; CHECK-SAME: () #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: ret void ; %a = load i32, i32* null ret void } define internal i32* @ret_null() { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_null ; IS__CGSCC____-SAME: () #[[ATTR0]] { ; IS__CGSCC____-NEXT: ret i32* null ; ret i32* null } define void @load_null_propagated() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@load_null_propagated ; IS__TUNIT____-SAME: () #[[ATTR0]] { ; IS__TUNIT____-NEXT: unreachable ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@load_null_propagated ; IS__CGSCC____-SAME: () #[[ATTR2:[0-9]+]] { ; IS__CGSCC____-NEXT: ret void ; %ptr = call i32* @ret_null() %a = load i32, i32* %ptr ret void } ; -- Store tests -- define void @store_wholly_unreachable() { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@store_wholly_unreachable ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: unreachable ; store i32 5, i32* null ret void } define void @store_wholly_unreachable_volatile() { ; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@store_wholly_unreachable_volatile ; IS__TUNIT____-SAME: () #[[ATTR2:[0-9]+]] { ; IS__TUNIT____-NEXT: store volatile i32 5, i32* null, align 4294967296 ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@store_wholly_unreachable_volatile ; IS__CGSCC____-SAME: () #[[ATTR3:[0-9]+]] { ; IS__CGSCC____-NEXT: store volatile i32 5, i32* null, align 4294967296 ; IS__CGSCC____-NEXT: ret void ; store volatile i32 5, i32* null ret void } define void @store_single_bb_unreachable(i1 %cond) { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@store_single_bb_unreachable ; CHECK-SAME: (i1 [[COND:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] ; CHECK: t: ; CHECK-NEXT: unreachable ; CHECK: e: ; CHECK-NEXT: ret void ; br i1 %cond, label %t, label %e t: store i32 5, i32* null br label %e e: ret void } define void @store_null_pointer_is_defined() null_pointer_is_valid { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly ; IS__TUNIT____-LABEL: define {{[^@]+}}@store_null_pointer_is_defined ; IS__TUNIT____-SAME: () #[[ATTR3:[0-9]+]] { ; IS__TUNIT____-NEXT: store i32 5, i32* null, align 4294967296 ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@store_null_pointer_is_defined ; IS__CGSCC____-SAME: () #[[ATTR4:[0-9]+]] { ; IS__CGSCC____-NEXT: store i32 5, i32* null, align 4294967296 ; IS__CGSCC____-NEXT: ret void ; store i32 5, i32* null ret void } define void @store_null_propagated() { ; ATTRIBUTOR-LABEL: @store_null_propagated( ; ATTRIBUTOR-NEXT: unreachable ; ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@store_null_propagated ; IS__TUNIT____-SAME: () #[[ATTR0]] { ; IS__TUNIT____-NEXT: unreachable ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@store_null_propagated ; IS__CGSCC____-SAME: () #[[ATTR5:[0-9]+]] { ; IS__CGSCC____-NEXT: [[PTR:%.*]] = call noalias align 4294967296 i32* @ret_null() #[[ATTR10:[0-9]+]] ; IS__CGSCC____-NEXT: ret void ; %ptr = call i32* @ret_null() store i32 5, i32* %ptr ret void } ; -- AtomicRMW tests -- define void @atomicrmw_wholly_unreachable() { ; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable ; IS__TUNIT____-SAME: () #[[ATTR2]] { ; IS__TUNIT____-NEXT: unreachable ; ; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable ; IS__CGSCC____-SAME: () #[[ATTR3]] { ; IS__CGSCC____-NEXT: unreachable ; %a = atomicrmw add i32* null, i32 1 acquire ret void } define void @atomicrmw_single_bb_unreachable(i1 %cond) { ; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_single_bb_unreachable ; IS__TUNIT____-SAME: (i1 [[COND:%.*]]) #[[ATTR2]] { ; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] ; IS__TUNIT____: t: ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: e: ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_single_bb_unreachable ; IS__CGSCC____-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { ; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: e: ; IS__CGSCC____-NEXT: ret void ; br i1 %cond, label %t, label %e t: %a = atomicrmw add i32* null, i32 1 acquire br label %e e: ret void } define void @atomicrmw_null_pointer_is_defined() null_pointer_is_valid { ; IS__TUNIT____: Function Attrs: nofree norecurse nounwind null_pointer_is_valid willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_null_pointer_is_defined ; IS__TUNIT____-SAME: () #[[ATTR4:[0-9]+]] { ; IS__TUNIT____-NEXT: [[A:%.*]] = atomicrmw add i32* null, i32 1 acquire, align 4 ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree norecurse nounwind null_pointer_is_valid willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_null_pointer_is_defined ; IS__CGSCC____-SAME: () #[[ATTR6:[0-9]+]] { ; IS__CGSCC____-NEXT: [[A:%.*]] = atomicrmw add i32* null, i32 1 acquire, align 4 ; IS__CGSCC____-NEXT: ret void ; %a = atomicrmw add i32* null, i32 1 acquire ret void } define void @atomicrmw_null_propagated() { ; ATTRIBUTOR-LABEL: @atomicrmw_null_propagated( ; ATTRIBUTOR-NEXT: unreachable ; ; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_null_propagated ; IS__TUNIT____-SAME: () #[[ATTR2]] { ; IS__TUNIT____-NEXT: unreachable ; ; IS__CGSCC____: Function Attrs: nofree nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_null_propagated ; IS__CGSCC____-SAME: () #[[ATTR7:[0-9]+]] { ; IS__CGSCC____-NEXT: [[PTR:%.*]] = call noalias i32* @ret_null() #[[ATTR10]] ; IS__CGSCC____-NEXT: [[A:%.*]] = atomicrmw add i32* [[PTR]], i32 1 acquire, align 4 ; IS__CGSCC____-NEXT: ret void ; %ptr = call i32* @ret_null() %a = atomicrmw add i32* %ptr, i32 1 acquire ret void } ; -- AtomicCmpXchg tests -- define void @atomiccmpxchg_wholly_unreachable() { ; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable ; IS__TUNIT____-SAME: () #[[ATTR2]] { ; IS__TUNIT____-NEXT: unreachable ; ; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable ; IS__CGSCC____-SAME: () #[[ATTR3]] { ; IS__CGSCC____-NEXT: unreachable ; %a = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic ret void } define void @atomiccmpxchg_single_bb_unreachable(i1 %cond) { ; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable ; IS__TUNIT____-SAME: (i1 [[COND:%.*]]) #[[ATTR2]] { ; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] ; IS__TUNIT____: t: ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: e: ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable ; IS__CGSCC____-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { ; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: e: ; IS__CGSCC____-NEXT: ret void ; br i1 %cond, label %t, label %e t: %a = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic br label %e e: ret void } define void @atomiccmpxchg_null_pointer_is_defined() null_pointer_is_valid { ; IS__TUNIT____: Function Attrs: nofree norecurse nounwind null_pointer_is_valid willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_pointer_is_defined ; IS__TUNIT____-SAME: () #[[ATTR4]] { ; IS__TUNIT____-NEXT: [[A:%.*]] = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic, align 4 ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree norecurse nounwind null_pointer_is_valid willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_pointer_is_defined ; IS__CGSCC____-SAME: () #[[ATTR6]] { ; IS__CGSCC____-NEXT: [[A:%.*]] = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic, align 4 ; IS__CGSCC____-NEXT: ret void ; %a = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic ret void } define void @atomiccmpxchg_null_propagated() { ; ATTRIBUTOR-LABEL: @atomiccmpxchg_null_propagated( ; ATTRIBUTOR-NEXT: unreachable ; ; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated ; IS__TUNIT____-SAME: () #[[ATTR2]] { ; IS__TUNIT____-NEXT: unreachable ; ; IS__CGSCC____: Function Attrs: nofree nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated ; IS__CGSCC____-SAME: () #[[ATTR7]] { ; IS__CGSCC____-NEXT: [[PTR:%.*]] = call noalias i32* @ret_null() #[[ATTR10]] ; IS__CGSCC____-NEXT: [[A:%.*]] = cmpxchg i32* [[PTR]], i32 2, i32 3 acq_rel monotonic, align 4 ; IS__CGSCC____-NEXT: ret void ; %ptr = call i32* @ret_null() %a = cmpxchg i32* %ptr, i32 2, i32 3 acq_rel monotonic ret void } ; -- Conditional branching tests -- ; Note: The unreachable on %t and %e is _not_ from AAUndefinedBehavior define i32 @cond_br_on_undef() { ; IS__TUNIT____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef ; IS__TUNIT____-SAME: () #[[ATTR5:[0-9]+]] { ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: t: ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: e: ; IS__TUNIT____-NEXT: unreachable ; ; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef ; IS__CGSCC____-SAME: () #[[ATTR8:[0-9]+]] { ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: e: ; IS__CGSCC____-NEXT: unreachable ; br i1 undef, label %t, label %e t: ret i32 1 e: ret i32 2 } ; More complicated branching ; Valid branch - verify that this is not converted ; to unreachable. define void @cond_br_on_undef2(i1 %cond) { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef2 ; CHECK-SAME: (i1 [[COND:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: br i1 [[COND]], label [[T1:%.*]], label [[E1:%.*]] ; CHECK: t1: ; CHECK-NEXT: unreachable ; CHECK: t2: ; CHECK-NEXT: unreachable ; CHECK: e2: ; CHECK-NEXT: unreachable ; CHECK: e1: ; CHECK-NEXT: ret void ; br i1 %cond, label %t1, label %e1 t1: br i1 undef, label %t2, label %e2 t2: ret void e2: ret void e1: ret void } define i1 @ret_undef() { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@ret_undef ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: ret i1 undef ; ret i1 undef } define void @cond_br_on_undef_interproc() { ; IS__TUNIT____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc ; IS__TUNIT____-SAME: () #[[ATTR5]] { ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: t: ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: e: ; IS__TUNIT____-NEXT: unreachable ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc ; IS__CGSCC____-SAME: () #[[ATTR2]] { ; IS__CGSCC____-NEXT: [[COND:%.*]] = call i1 @ret_undef() #[[ATTR10]] ; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: ret void ; IS__CGSCC____: e: ; IS__CGSCC____-NEXT: ret void ; %cond = call i1 @ret_undef() br i1 %cond, label %t, label %e t: ret void e: ret void } define i1 @ret_undef2() { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@ret_undef2 ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: br i1 true, label [[T:%.*]], label [[E:%.*]] ; CHECK: t: ; CHECK-NEXT: ret i1 undef ; CHECK: e: ; CHECK-NEXT: unreachable ; br i1 true, label %t, label %e t: ret i1 undef e: ret i1 undef } ; More complicated interproc deduction of undef define void @cond_br_on_undef_interproc2() { ; IS__TUNIT____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc2 ; IS__TUNIT____-SAME: () #[[ATTR5]] { ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: t: ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: e: ; IS__TUNIT____-NEXT: unreachable ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc2 ; IS__CGSCC____-SAME: () #[[ATTR2]] { ; IS__CGSCC____-NEXT: [[COND:%.*]] = call i1 @ret_undef2() #[[ATTR10]] ; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: ret void ; IS__CGSCC____: e: ; IS__CGSCC____-NEXT: ret void ; %cond = call i1 @ret_undef2() br i1 %cond, label %t, label %e t: ret void e: ret void } ; Branch on undef that depends on propagation of ; undef of a previous instruction. define i32 @cond_br_on_undef3() { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef3 ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 1, undef ; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] ; CHECK: t: ; CHECK-NEXT: ret i32 1 ; CHECK: e: ; CHECK-NEXT: ret i32 2 ; %cond = icmp ne i32 1, undef br i1 %cond, label %t, label %e t: ret i32 1 e: ret i32 2 } ; Branch on undef because of uninitialized value. ; FIXME: Currently it doesn't propagate the undef. define i32 @cond_br_on_undef_uninit() { ; IS__TUNIT____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef_uninit ; IS__TUNIT____-SAME: () #[[ATTR5]] { ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: t: ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: e: ; IS__TUNIT____-NEXT: unreachable ; ; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef_uninit ; IS__CGSCC____-SAME: () #[[ATTR8]] { ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: e: ; IS__CGSCC____-NEXT: unreachable ; %alloc = alloca i1 %cond = load i1, i1* %alloc br i1 %cond, label %t, label %e t: ret i32 1 e: ret i32 2 } ; Note that the `load` has UB (so it will be changed to unreachable) ; and the branch is a terminator that can be constant-folded. ; We want to test that doing both won't cause a segfault. ; MODULE-NOT: @callee( define internal i32 @callee(i1 %C, i32* %A) { ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@callee ; IS__CGSCC____-SAME: () #[[ATTR0]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: T: ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: F: ; IS__CGSCC____-NEXT: ret i32 1 ; entry: %A.0 = load i32, i32* null br i1 %C, label %T, label %F T: ret i32 %A.0 F: ret i32 1 } define i32 @foo() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@foo ; IS__TUNIT____-SAME: () #[[ATTR0]] { ; IS__TUNIT____-NEXT: ret i32 1 ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@foo ; IS__CGSCC____-SAME: () #[[ATTR2]] { ; IS__CGSCC____-NEXT: [[X:%.*]] = call noundef i32 @callee() #[[ATTR10]] ; IS__CGSCC____-NEXT: ret i32 [[X]] ; %X = call i32 @callee(i1 false, i32* null) ret i32 %X } ; Tests for nonnull noundef attribute violation. ; ; Tests for argument position define void @arg_nonnull_1(i32* nonnull %a) { ; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_1 ; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] { ; IS__TUNIT____-NEXT: store i32 0, i32* [[A]], align 4 ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_1 ; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR9:[0-9]+]] { ; IS__CGSCC____-NEXT: store i32 0, i32* [[A]], align 4 ; IS__CGSCC____-NEXT: ret void ; store i32 0, i32* %a ret void } define void @arg_nonnull_1_noundef_1(i32* nonnull noundef %a) { ; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_1_noundef_1 ; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6]] { ; IS__TUNIT____-NEXT: store i32 0, i32* [[A]], align 4 ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_1_noundef_1 ; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR9]] { ; IS__CGSCC____-NEXT: store i32 0, i32* [[A]], align 4 ; IS__CGSCC____-NEXT: ret void ; store i32 0, i32* %a ret void } define void @arg_nonnull_12(i32* nonnull %a, i32* nonnull %b, i32* %c) { ; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_12 ; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR6]] { ; IS__TUNIT____-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null ; IS__TUNIT____-NEXT: br i1 [[D]], label [[T:%.*]], label [[F:%.*]] ; IS__TUNIT____: t: ; IS__TUNIT____-NEXT: store i32 0, i32* [[A]], align 4 ; IS__TUNIT____-NEXT: br label [[RET:%.*]] ; IS__TUNIT____: f: ; IS__TUNIT____-NEXT: store i32 1, i32* [[B]], align 4 ; IS__TUNIT____-NEXT: br label [[RET]] ; IS__TUNIT____: ret: ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_12 ; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR9]] { ; IS__CGSCC____-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null ; IS__CGSCC____-NEXT: br i1 [[D]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: store i32 0, i32* [[A]], align 4 ; IS__CGSCC____-NEXT: br label [[RET:%.*]] ; IS__CGSCC____: f: ; IS__CGSCC____-NEXT: store i32 1, i32* [[B]], align 4 ; IS__CGSCC____-NEXT: br label [[RET]] ; IS__CGSCC____: ret: ; IS__CGSCC____-NEXT: ret void ; %d = icmp eq i32* %c, null br i1 %d, label %t, label %f t: store i32 0, i32* %a br label %ret f: store i32 1, i32* %b br label %ret ret: ret void } define void @arg_nonnull_12_noundef_2(i32* nonnull %a, i32* noundef nonnull %b, i32* %c) { ; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_12_noundef_2 ; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree noundef nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR6]] { ; IS__TUNIT____-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null ; IS__TUNIT____-NEXT: br i1 [[D]], label [[T:%.*]], label [[F:%.*]] ; IS__TUNIT____: t: ; IS__TUNIT____-NEXT: store i32 0, i32* [[A]], align 4 ; IS__TUNIT____-NEXT: br label [[RET:%.*]] ; IS__TUNIT____: f: ; IS__TUNIT____-NEXT: store i32 1, i32* [[B]], align 4 ; IS__TUNIT____-NEXT: br label [[RET]] ; IS__TUNIT____: ret: ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_12_noundef_2 ; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree noundef nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR9]] { ; IS__CGSCC____-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null ; IS__CGSCC____-NEXT: br i1 [[D]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: store i32 0, i32* [[A]], align 4 ; IS__CGSCC____-NEXT: br label [[RET:%.*]] ; IS__CGSCC____: f: ; IS__CGSCC____-NEXT: store i32 1, i32* [[B]], align 4 ; IS__CGSCC____-NEXT: br label [[RET]] ; IS__CGSCC____: ret: ; IS__CGSCC____-NEXT: ret void ; %d = icmp eq i32* %c, null br i1 %d, label %t, label %f t: store i32 0, i32* %a br label %ret f: store i32 1, i32* %b br label %ret ret: ret void } ; Pass null directly to argument with nonnull attribute define void @arg_nonnull_violation1_1() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_violation1_1 ; IS__TUNIT____-SAME: () #[[ATTR0]] { ; IS__TUNIT____-NEXT: unreachable ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation1_1 ; IS__CGSCC____-SAME: () #[[ATTR2]] { ; IS__CGSCC____-NEXT: unreachable ; call void @arg_nonnull_1(i32* null) ret void } define void @arg_nonnull_violation1_2() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_violation1_2 ; IS__TUNIT____-SAME: () #[[ATTR0]] { ; IS__TUNIT____-NEXT: unreachable ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation1_2 ; IS__CGSCC____-SAME: () #[[ATTR2]] { ; IS__CGSCC____-NEXT: unreachable ; call void @arg_nonnull_1_noundef_1(i32* null) ret void } ; A case that depends on value simplification define void @arg_nonnull_violation2_1(i1 %c) { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_violation2_1 ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; IS__TUNIT____-NEXT: unreachable ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation2_1 ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC____-NEXT: unreachable ; %null = getelementptr i32, i32* null, i32 0 %mustnull = select i1 %c, i32* null, i32* %null call void @arg_nonnull_1(i32* %mustnull) ret void } define void @arg_nonnull_violation2_2(i1 %c) { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_violation2_2 ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; IS__TUNIT____-NEXT: unreachable ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation2_2 ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC____-NEXT: unreachable ; %null = getelementptr i32, i32* null, i32 0 %mustnull = select i1 %c, i32* null, i32* %null call void @arg_nonnull_1_noundef_1(i32* %mustnull) ret void } ; Cases for single and multiple violation at a callsite define void @arg_nonnull_violation3_1(i1 %c) { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_violation3_1 ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; IS__TUNIT____-NEXT: [[PTR:%.*]] = alloca i32, align 4 ; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__TUNIT____: t: ; IS__TUNIT____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR7:[0-9]+]] ; IS__TUNIT____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 4294967296 null) #[[ATTR7]] ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: f: ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: ret: ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation3_1 ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC____-NEXT: [[PTR:%.*]] = alloca i32, align 4 ; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR11:[0-9]+]] ; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 4294967296 null) #[[ATTR11]] ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: f: ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: ret: ; IS__CGSCC____-NEXT: ret void ; %ptr = alloca i32 br i1 %c, label %t, label %f t: call void @arg_nonnull_12(i32* %ptr, i32* %ptr, i32* %ptr) call void @arg_nonnull_12(i32* %ptr, i32* %ptr, i32* null) call void @arg_nonnull_12(i32* %ptr, i32* null, i32* %ptr) call void @arg_nonnull_12(i32* %ptr, i32* null, i32* null) br label %ret f: call void @arg_nonnull_12(i32* null, i32* %ptr, i32* %ptr) call void @arg_nonnull_12(i32* null, i32* %ptr, i32* null) call void @arg_nonnull_12(i32* null, i32* null, i32* %ptr) call void @arg_nonnull_12(i32* null, i32* null, i32* null) br label %ret ret: ret void } define void @arg_nonnull_violation3_2(i1 %c) { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_violation3_2 ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; IS__TUNIT____-NEXT: [[PTR:%.*]] = alloca i32, align 4 ; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__TUNIT____: t: ; IS__TUNIT____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR7]] ; IS__TUNIT____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 4294967296 null) #[[ATTR7]] ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: f: ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: ret: ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation3_2 ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC____-NEXT: [[PTR:%.*]] = alloca i32, align 4 ; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR11]] ; IS__CGSCC____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 4294967296 null) #[[ATTR11]] ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: f: ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: ret: ; IS__CGSCC____-NEXT: ret void ; %ptr = alloca i32 br i1 %c, label %t, label %f t: call void @arg_nonnull_12_noundef_2(i32* %ptr, i32* %ptr, i32* %ptr) call void @arg_nonnull_12_noundef_2(i32* %ptr, i32* %ptr, i32* null) call void @arg_nonnull_12_noundef_2(i32* %ptr, i32* null, i32* %ptr) call void @arg_nonnull_12_noundef_2(i32* %ptr, i32* null, i32* null) br label %ret f: call void @arg_nonnull_12_noundef_2(i32* null, i32* %ptr, i32* %ptr) call void @arg_nonnull_12_noundef_2(i32* null, i32* %ptr, i32* null) call void @arg_nonnull_12_noundef_2(i32* null, i32* null, i32* %ptr) call void @arg_nonnull_12_noundef_2(i32* null, i32* null, i32* null) br label %ret ret: ret void } ; Tests for returned position define nonnull i32* @returned_nonnnull(i32 %c) { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@returned_nonnnull ; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: switch i32 [[C]], label [[ONDEFAULT:%.*]] [ ; CHECK-NEXT: i32 0, label [[ONZERO:%.*]] ; CHECK-NEXT: i32 1, label [[ONONE:%.*]] ; CHECK-NEXT: ] ; CHECK: onzero: ; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 4 ; CHECK-NEXT: ret i32* [[PTR]] ; CHECK: onone: ; CHECK-NEXT: ret i32* null ; CHECK: ondefault: ; CHECK-NEXT: ret i32* undef ; switch i32 %c, label %ondefault [ i32 0, label %onzero i32 1, label %onone ] onzero: %ptr = alloca i32 ret i32* %ptr onone: ret i32* null ondefault: ret i32* undef } define noundef i32* @returned_noundef(i32 %c) { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@returned_noundef ; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: switch i32 [[C]], label [[ONDEFAULT:%.*]] [ ; CHECK-NEXT: i32 0, label [[ONZERO:%.*]] ; CHECK-NEXT: i32 1, label [[ONONE:%.*]] ; CHECK-NEXT: ] ; CHECK: onzero: ; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 4 ; CHECK-NEXT: ret i32* [[PTR]] ; CHECK: onone: ; CHECK-NEXT: ret i32* null ; CHECK: ondefault: ; CHECK-NEXT: unreachable ; switch i32 %c, label %ondefault [ i32 0, label %onzero i32 1, label %onone ] onzero: %ptr = alloca i32 ret i32* %ptr onone: ret i32* null ondefault: ret i32* undef } define nonnull noundef i32* @returned_nonnnull_noundef(i32 %c) { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@returned_nonnnull_noundef ; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: switch i32 [[C]], label [[ONDEFAULT:%.*]] [ ; CHECK-NEXT: i32 0, label [[ONZERO:%.*]] ; CHECK-NEXT: i32 1, label [[ONONE:%.*]] ; CHECK-NEXT: ] ; CHECK: onzero: ; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 4 ; CHECK-NEXT: ret i32* [[PTR]] ; CHECK: onone: ; CHECK-NEXT: unreachable ; CHECK: ondefault: ; CHECK-NEXT: unreachable ; switch i32 %c, label %ondefault [ i32 0, label %onzero i32 1, label %onone ] onzero: %ptr = alloca i32 ret i32* %ptr onone: ret i32* null ondefault: ret i32* undef } define noundef i32 @returned_nonnnull_noundef_int() { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@returned_nonnnull_noundef_int ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: ret i32 0 ; ret i32 0 } declare void @callee_int_arg(i32) define void @callsite_noundef_1() { ; CHECK-LABEL: define {{[^@]+}}@callsite_noundef_1() { ; CHECK-NEXT: call void @callee_int_arg(i32 noundef 0) ; CHECK-NEXT: ret void ; call void @callee_int_arg(i32 noundef 0) ret void } declare void @callee_ptr_arg(i32*) define void @callsite_noundef_2() { ; CHECK-LABEL: define {{[^@]+}}@callsite_noundef_2() { ; CHECK-NEXT: unreachable ; call void @callee_ptr_arg(i32* noundef undef) ret void } define i32 @argument_noundef1(i32 noundef %c) { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@argument_noundef1 ; CHECK-SAME: (i32 noundef returned [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: ret i32 [[C]] ; ret i32 %c } define i32 @violate_noundef_nonpointer() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@violate_noundef_nonpointer ; IS__TUNIT____-SAME: () #[[ATTR0]] { ; IS__TUNIT____-NEXT: ret i32 undef ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@violate_noundef_nonpointer ; IS__CGSCC____-SAME: () #[[ATTR2]] { ; IS__CGSCC____-NEXT: unreachable ; %ret = call i32 @argument_noundef1(i32 undef) ret i32 %ret } define i32* @argument_noundef2(i32* noundef %c) { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@argument_noundef2 ; CHECK-SAME: (i32* nofree noundef readnone returned "no-capture-maybe-returned" [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: ret i32* [[C]] ; ret i32* %c } define i32* @violate_noundef_pointer() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@violate_noundef_pointer ; IS__TUNIT____-SAME: () #[[ATTR0]] { ; IS__TUNIT____-NEXT: ret i32* undef ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@violate_noundef_pointer ; IS__CGSCC____-SAME: () #[[ATTR2]] { ; IS__CGSCC____-NEXT: ret i32* undef ; %ret = call i32* @argument_noundef2(i32* undef) ret i32* %ret } define internal noundef i32 @assumed_undef_is_ok(i1 %c, i32 %arg) { ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@assumed_undef_is_ok ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC____-NEXT: br i1 [[C]], label [[REC:%.*]], label [[RET:%.*]] ; IS__CGSCC____: rec: ; IS__CGSCC____-NEXT: br label [[RET]] ; IS__CGSCC____: ret: ; IS__CGSCC____-NEXT: ret i32 0 ; %stack = alloca i32 store i32 %arg, i32* %stack br i1 %c, label %rec, label %ret rec: %call = call i32 @assumed_undef_is_ok(i1 false, i32 0) store i32 %call, i32* %stack br label %ret ret: %l = load i32, i32* %stack ret i32 %l } define noundef i32 @assumed_undef_is_ok_caller(i1 %c) { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@assumed_undef_is_ok_caller ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { ; IS__TUNIT____-NEXT: ret i32 0 ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@assumed_undef_is_ok_caller ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @assumed_undef_is_ok(i1 [[C]]) #[[ATTR10]] ; IS__CGSCC____-NEXT: ret i32 [[CALL]] ; %call = call i32 @assumed_undef_is_ok(i1 %c, i32 undef) ret i32 %call } ;. ; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__TUNIT____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } ; IS__TUNIT____: attributes #[[ATTR2]] = { nofree norecurse nounwind readnone willreturn } ; IS__TUNIT____: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly } ; IS__TUNIT____: attributes #[[ATTR4]] = { nofree norecurse nounwind null_pointer_is_valid willreturn } ; IS__TUNIT____: attributes #[[ATTR5]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } ; IS__TUNIT____: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } ; IS__TUNIT____: attributes #[[ATTR7]] = { nofree nosync nounwind willreturn writeonly } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR3]] = { nofree norecurse nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly } ; IS__CGSCC____: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn writeonly } ; IS__CGSCC____: attributes #[[ATTR6]] = { nofree norecurse nounwind null_pointer_is_valid willreturn } ; IS__CGSCC____: attributes #[[ATTR7]] = { nofree nounwind willreturn } ; IS__CGSCC____: attributes #[[ATTR8]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR9]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } ; IS__CGSCC____: attributes #[[ATTR10]] = { readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR11]] = { nounwind willreturn writeonly } ;.