; 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=13 -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=13 -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:o-i64:64-f80:128-n8:16:32:64-S128" declare void @f(i32) declare token @llvm.call.preallocated.setup(i32) declare i8* @llvm.call.preallocated.arg(token, i32) @ConstAS3Ptr = addrspace(3) global i32 0, align 4 ;. ; CHECK: @[[CONSTAS3PTR:[a-zA-Z0-9_$"\\.-]+]] = addrspace(3) global i32 0, align 4 ; CHECK: @[[S:[a-zA-Z0-9_$"\\.-]+]] = external global [[STRUCT_X:%.*]] ; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = internal constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (void (i8***)* @f1 to i8*), i8* bitcast (void (i1 (i8*)*)* @f2 to i8*)] } ;. define internal i32 addrspace(3)* @const_ptr_return_as3() { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@const_ptr_return_as3 ; IS__CGSCC____-SAME: () #[[ATTR1:[0-9]+]] { ; IS__CGSCC____-NEXT: ret i32 addrspace(3)* @ConstAS3Ptr ; ret i32 addrspace(3)* @ConstAS3Ptr } define internal i32* @const_ptr_return() { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@const_ptr_return ; IS__CGSCC____-SAME: () #[[ATTR1]] { ; IS__CGSCC____-NEXT: ret i32* addrspacecast (i32 addrspace(3)* @ConstAS3Ptr to i32*) ; ret i32* addrspacecast (i32 addrspace(3)* @ConstAS3Ptr to i32*) } ; Test1: Replace argument with constant define internal void @test1(i32 %a) { ; CHECK-LABEL: define {{[^@]+}}@test1() { ; CHECK-NEXT: tail call void @f(i32 noundef 1) ; CHECK-NEXT: ret void ; tail call void @f(i32 %a) ret void } define void @test1_helper() { ; CHECK-LABEL: define {{[^@]+}}@test1_helper() { ; CHECK-NEXT: tail call void @test1() ; CHECK-NEXT: ret void ; tail call void @test1(i32 1) ret void } ; TEST 2 : Simplify return value define i32 @return0() { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@return0 ; CHECK-SAME: () #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: ret i32 0 ; ret i32 0 } define i32 @return1() { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@return1 ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: ret i32 1 ; ret i32 1 } define i32 @test2_1(i1 %c) { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_1 ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; IS__TUNIT____-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] ; IS__TUNIT____: if.true: ; IS__TUNIT____-NEXT: [[RET0:%.*]] = add i32 0, 1 ; IS__TUNIT____-NEXT: br label [[END:%.*]] ; IS__TUNIT____: if.false: ; IS__TUNIT____-NEXT: br label [[END]] ; IS__TUNIT____: end: ; IS__TUNIT____-NEXT: [[RET:%.*]] = phi i32 [ [[RET0]], [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ] ; IS__TUNIT____-NEXT: ret i32 1 ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test2_1 ; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] ; IS__CGSCC_OPM: if.true: ; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = tail call i32 @return0() #[[ATTR13:[0-9]+]] ; IS__CGSCC_OPM-NEXT: [[RET0:%.*]] = add i32 [[CALL]], 1 ; IS__CGSCC_OPM-NEXT: br label [[END:%.*]] ; IS__CGSCC_OPM: if.false: ; IS__CGSCC_OPM-NEXT: [[RET1:%.*]] = tail call i32 @return1() #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: br label [[END]] ; IS__CGSCC_OPM: end: ; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = phi i32 [ [[RET0]], [[IF_TRUE]] ], [ [[RET1]], [[IF_FALSE]] ] ; IS__CGSCC_OPM-NEXT: ret i32 1 ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test2_1 ; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] ; IS__CGSCC_NPM: if.true: ; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = tail call i32 @return0() #[[ATTR12:[0-9]+]] ; IS__CGSCC_NPM-NEXT: [[RET0:%.*]] = add i32 [[CALL]], 1 ; IS__CGSCC_NPM-NEXT: br label [[END:%.*]] ; IS__CGSCC_NPM: if.false: ; IS__CGSCC_NPM-NEXT: [[RET1:%.*]] = tail call i32 @return1() #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: br label [[END]] ; IS__CGSCC_NPM: end: ; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = phi i32 [ [[RET0]], [[IF_TRUE]] ], [ [[RET1]], [[IF_FALSE]] ] ; IS__CGSCC_NPM-NEXT: ret i32 1 ; br i1 %c, label %if.true, label %if.false if.true: %call = tail call i32 @return0() %ret0 = add i32 %call, 1 br label %end if.false: %ret1 = tail call i32 @return1() br label %end end: %ret = phi i32 [ %ret0, %if.true ], [ %ret1, %if.false ] ret i32 1 } define i32 @test2_2(i1 %c) { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_2 ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; IS__TUNIT____-NEXT: ret i32 1 ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test2_2 ; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = tail call noundef i32 @test2_1(i1 [[C]]) #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test2_2 ; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = tail call noundef i32 @test2_1(i1 [[C]]) #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] ; %ret = tail call i32 @test2_1(i1 %c) ret i32 %ret } declare void @use(i32) define void @test3(i1 %c) { ; IS__TUNIT____-LABEL: define {{[^@]+}}@test3 ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) { ; IS__TUNIT____-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] ; IS__TUNIT____: if.true: ; IS__TUNIT____-NEXT: br label [[END:%.*]] ; IS__TUNIT____: if.false: ; IS__TUNIT____-NEXT: br label [[END]] ; IS__TUNIT____: end: ; IS__TUNIT____-NEXT: [[R:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ] ; IS__TUNIT____-NEXT: tail call void @use(i32 noundef 1) ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test3 ; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) { ; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] ; IS__CGSCC_OPM: if.true: ; IS__CGSCC_OPM-NEXT: br label [[END:%.*]] ; IS__CGSCC_OPM: if.false: ; IS__CGSCC_OPM-NEXT: [[RET1:%.*]] = tail call i32 @return1() #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: br label [[END]] ; IS__CGSCC_OPM: end: ; IS__CGSCC_OPM-NEXT: [[R:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ [[RET1]], [[IF_FALSE]] ] ; IS__CGSCC_OPM-NEXT: tail call void @use(i32 noundef [[R]]) ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test3 ; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) { ; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] ; IS__CGSCC_NPM: if.true: ; IS__CGSCC_NPM-NEXT: br label [[END:%.*]] ; IS__CGSCC_NPM: if.false: ; IS__CGSCC_NPM-NEXT: [[RET1:%.*]] = tail call i32 @return1() #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: br label [[END]] ; IS__CGSCC_NPM: end: ; IS__CGSCC_NPM-NEXT: [[R:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ [[RET1]], [[IF_FALSE]] ] ; IS__CGSCC_NPM-NEXT: tail call void @use(i32 noundef [[R]]) ; IS__CGSCC_NPM-NEXT: ret void ; br i1 %c, label %if.true, label %if.false if.true: br label %end if.false: %ret1 = tail call i32 @return1() br label %end end: %r = phi i32 [ 1, %if.true ], [ %ret1, %if.false ] tail call void @use(i32 %r) ret void } define void @test-select-phi(i1 %c) { ; CHECK-LABEL: define {{[^@]+}}@test-select-phi ; CHECK-SAME: (i1 [[C:%.*]]) { ; CHECK-NEXT: tail call void @use(i32 noundef 1) ; CHECK-NEXT: [[SELECT_NOT_SAME:%.*]] = select i1 [[C]], i32 1, i32 0 ; CHECK-NEXT: tail call void @use(i32 noundef [[SELECT_NOT_SAME]]) ; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] ; CHECK: if-true: ; CHECK-NEXT: br label [[END:%.*]] ; CHECK: if-false: ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[PHI_SAME:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ] ; CHECK-NEXT: [[PHI_NOT_SAME:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ] ; CHECK-NEXT: [[PHI_SAME_PROP:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ] ; CHECK-NEXT: [[PHI_SAME_UNDEF:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ undef, [[IF_FALSE]] ] ; CHECK-NEXT: [[SELECT_NOT_SAME_UNDEF:%.*]] = select i1 [[C]], i32 [[PHI_NOT_SAME]], i32 undef ; CHECK-NEXT: tail call void @use(i32 noundef 1) ; CHECK-NEXT: tail call void @use(i32 noundef [[PHI_NOT_SAME]]) ; CHECK-NEXT: tail call void @use(i32 noundef 1) ; CHECK-NEXT: tail call void @use(i32 1) ; CHECK-NEXT: tail call void @use(i32 [[SELECT_NOT_SAME_UNDEF]]) ; CHECK-NEXT: ret void ; %select-same = select i1 %c, i32 1, i32 1 tail call void @use(i32 %select-same) %select-not-same = select i1 %c, i32 1, i32 0 tail call void @use(i32 %select-not-same) br i1 %c, label %if-true, label %if-false if-true: br label %end if-false: br label %end end: %phi-same = phi i32 [ 1, %if-true ], [ 1, %if-false ] %phi-not-same = phi i32 [ 0, %if-true ], [ 1, %if-false ] %phi-same-prop = phi i32 [ 1, %if-true ], [ %select-same, %if-false ] %phi-same-undef = phi i32 [ 1, %if-true ], [ undef, %if-false ] %select-not-same-undef = select i1 %c, i32 %phi-not-same, i32 undef tail call void @use(i32 %phi-same) tail call void @use(i32 %phi-not-same) tail call void @use(i32 %phi-same-prop) tail call void @use(i32 %phi-same-undef) tail call void @use(i32 %select-not-same-undef) ret void } define i32 @ipccp1(i32 %a) { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@ipccp1 ; CHECK-SAME: (i32 returned [[A:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: br i1 true, label [[T:%.*]], label [[F:%.*]] ; CHECK: t: ; CHECK-NEXT: ret i32 [[A]] ; CHECK: f: ; CHECK-NEXT: unreachable ; br i1 true, label %t, label %f t: ret i32 %a f: %r = call i32 @ipccp1(i32 5) ret i32 %r } define internal i1 @ipccp2i(i1 %a) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp2i ; IS__CGSCC____-SAME: () #[[ATTR1]] { ; IS__CGSCC____-NEXT: br label [[T:%.*]] ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: ret i1 true ; IS__CGSCC____: f: ; IS__CGSCC____-NEXT: unreachable ; br i1 %a, label %t, label %f t: ret i1 %a f: %r = call i1 @ipccp2i(i1 false) ret i1 %r } define i1 @ipccp2() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@ipccp2 ; IS__TUNIT____-SAME: () #[[ATTR1]] { ; IS__TUNIT____-NEXT: ret i1 true ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ipccp2 ; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call noundef i1 @ipccp2i() #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret i1 [[R]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ipccp2 ; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call noundef i1 @ipccp2i() #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret i1 [[R]] ; %r = call i1 @ipccp2i(i1 true) ret i1 %r } define internal i1 @ipccp2ib(i1 %a) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp2ib ; IS__CGSCC____-SAME: () #[[ATTR1]] { ; IS__CGSCC____-NEXT: br label [[T:%.*]] ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: ret i1 true ; IS__CGSCC____: f: ; IS__CGSCC____-NEXT: unreachable ; br i1 %a, label %t, label %f t: ret i1 true f: %r = call i1 @ipccp2ib(i1 false) ret i1 %r } define i1 @ipccp2b() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@ipccp2b ; IS__TUNIT____-SAME: () #[[ATTR1]] { ; IS__TUNIT____-NEXT: ret i1 true ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ipccp2b ; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call noundef i1 @ipccp2ib() #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret i1 [[R]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ipccp2b ; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call noundef i1 @ipccp2ib() #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret i1 [[R]] ; %r = call i1 @ipccp2ib(i1 true) ret i1 %r } define internal i32 @ipccp3i(i32 %a) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp3i ; IS__CGSCC____-SAME: () #[[ATTR1]] { ; IS__CGSCC____-NEXT: br label [[T:%.*]] ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: ret i32 7 ; IS__CGSCC____: f: ; IS__CGSCC____-NEXT: unreachable ; %c = icmp eq i32 %a, 7 br i1 %c, label %t, label %f t: ret i32 %a f: %r = call i32 @ipccp3i(i32 5) ret i32 %r } define i32 @ipccp3() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@ipccp3 ; IS__TUNIT____-SAME: () #[[ATTR1]] { ; IS__TUNIT____-NEXT: ret i32 7 ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ipccp3 ; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call noundef i32 @ipccp3i() #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret i32 [[R]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ipccp3 ; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call noundef i32 @ipccp3i() #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret i32 [[R]] ; %r = call i32 @ipccp3i(i32 7) ret i32 %r } define internal i32 @ipccp4ia(i1 %c) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp4ia ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: ret i32 0 ; IS__CGSCC____: f: ; IS__CGSCC____-NEXT: ret i32 1 ; br i1 %c, label %t, label %f t: ret i32 0 f: ret i32 1 } define internal i32 @ipccp4ib(i32 %a) { ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ipccp4ib ; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: br label [[T:%.*]] ; IS__CGSCC_OPM: t: ; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call noundef i32 @ipccp4ia(i1 noundef true) #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret i32 [[R]] ; IS__CGSCC_OPM: f: ; IS__CGSCC_OPM-NEXT: unreachable ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ipccp4ib ; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: br label [[T:%.*]] ; IS__CGSCC_NPM: t: ; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call noundef i32 @ipccp4ia(i1 noundef true) #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret i32 [[R]] ; IS__CGSCC_NPM: f: ; IS__CGSCC_NPM-NEXT: unreachable ; %c = icmp eq i32 %a, 7 br i1 %c, label %t, label %f t: %r = call i32 @ipccp4ia(i1 %c) ret i32 %r f: ret i32 1 } define i32 @ipccp4(i1 %c) { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@ipccp4 ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__TUNIT____: t: ; IS__TUNIT____-NEXT: br label [[F]] ; IS__TUNIT____: f: ; IS__TUNIT____-NEXT: ret i32 0 ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ipccp4 ; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC_OPM: t: ; IS__CGSCC_OPM-NEXT: br label [[F]] ; IS__CGSCC_OPM: f: ; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call noundef i32 @ipccp4ib() #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret i32 [[R]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ipccp4 ; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC_NPM: t: ; IS__CGSCC_NPM-NEXT: br label [[F]] ; IS__CGSCC_NPM: f: ; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call noundef i32 @ipccp4ib() #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret i32 [[R]] ; br i1 %c, label %t, label %f t: %q = call i32 @ipccp4ia(i1 undef) br label %f f: %r = call i32 @ipccp4ib(i32 7) ret i32 %r } ; Do not touch complicated arguments (for now) %struct.X = type { i8* } define internal i32* @test_inalloca(i32* inalloca(i32) %a) { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@test_inalloca ; CHECK-SAME: (i32* noalias nofree nonnull returned writeonly inalloca(i32) dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: ret i32* [[A]] ; ret i32* %a } define i32* @complicated_args_inalloca(i32* %arg) { ; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@complicated_args_inalloca ; IS__TUNIT_OPM-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR1]] { ; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call nonnull dereferenceable(4) i32* @test_inalloca(i32* noalias nofree writeonly inalloca(i32) "no-capture-maybe-returned" [[ARG]]) #[[ATTR10:[0-9]+]] ; IS__TUNIT_OPM-NEXT: ret i32* [[CALL]] ; ; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@complicated_args_inalloca ; IS__TUNIT_NPM-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR1]] { ; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call nonnull dereferenceable(4) i32* @test_inalloca(i32* noalias nofree writeonly inalloca(i32) "no-capture-maybe-returned" [[ARG]]) #[[ATTR9:[0-9]+]] ; IS__TUNIT_NPM-NEXT: ret i32* [[CALL]] ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_inalloca ; IS__CGSCC_OPM-SAME: (i32* nofree noundef nonnull readnone dereferenceable(4) [[ARG:%.*]]) #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias nonnull dereferenceable(4) i32* @test_inalloca(i32* noalias nofree noundef nonnull writeonly inalloca(i32) dereferenceable(4) [[ARG]]) #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret i32* [[CALL]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_inalloca ; IS__CGSCC_NPM-SAME: (i32* nofree noundef nonnull readnone dereferenceable(4) [[ARG:%.*]]) #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call noalias nonnull dereferenceable(4) i32* @test_inalloca(i32* noalias nofree noundef nonnull writeonly inalloca(i32) dereferenceable(4) [[ARG]]) #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret i32* [[CALL]] ; %call = call i32* @test_inalloca(i32* inalloca(i32) %arg) ret i32* %call } define internal i32* @test_preallocated(i32* preallocated(i32) %a) { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@test_preallocated ; CHECK-SAME: (i32* noalias nofree noundef nonnull returned writeonly preallocated(i32) align 4294967296 dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: ret i32* [[A]] ; ret i32* %a } define i32* @complicated_args_preallocated() { ; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@complicated_args_preallocated ; IS__TUNIT_OPM-SAME: () #[[ATTR2:[0-9]+]] { ; IS__TUNIT_OPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR11:[0-9]+]] ; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noundef nonnull align 4294967296 dereferenceable(4) i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 4294967296 null) #[[ATTR10]] [ "preallocated"(token [[C]]) ] ; IS__TUNIT_OPM-NEXT: ret i32* [[CALL]] ; ; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@complicated_args_preallocated ; IS__TUNIT_NPM-SAME: () #[[ATTR2:[0-9]+]] { ; IS__TUNIT_NPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR10:[0-9]+]] ; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call noundef nonnull align 4294967296 dereferenceable(4) i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 4294967296 null) #[[ATTR9]] [ "preallocated"(token [[C]]) ] ; IS__TUNIT_NPM-NEXT: ret i32* [[CALL]] ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_preallocated ; IS__CGSCC_OPM-SAME: () #[[ATTR3:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR14:[0-9]+]] ; IS__CGSCC_OPM-NEXT: ret i32* null ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_preallocated ; IS__CGSCC_NPM-SAME: () #[[ATTR3:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR13:[0-9]+]] ; IS__CGSCC_NPM-NEXT: ret i32* null ; %c = call token @llvm.call.preallocated.setup(i32 1) %call = call i32* @test_preallocated(i32* preallocated(i32) null) ["preallocated"(token %c)] ret i32* %call } define internal void @test_sret(%struct.X* sret(%struct.X) %a, %struct.X** %b) { ; ; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__TUNIT____-LABEL: define {{[^@]+}}@test_sret ; IS__TUNIT____-SAME: (%struct.X* noalias nofree noundef nonnull writeonly sret([[STRUCT_X:%.*]]) align 4294967296 dereferenceable(8) [[A:%.*]], %struct.X** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR3:[0-9]+]] { ; IS__TUNIT____-NEXT: store %struct.X* [[A]], %struct.X** [[B]], align 8 ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@test_sret ; IS__CGSCC____-SAME: (%struct.X* noalias nofree noundef nonnull writeonly sret([[STRUCT_X:%.*]]) align 4294967296 dereferenceable(8) [[A:%.*]], %struct.X** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR4:[0-9]+]] { ; IS__CGSCC____-NEXT: store %struct.X* [[A]], %struct.X** [[B]], align 8 ; IS__CGSCC____-NEXT: ret void ; store %struct.X* %a, %struct.X** %b ret void } ; FIXME: Alignment and dereferenceability are not propagated to the argument define void @complicated_args_sret(%struct.X** %b) { ; ; ; IS__TUNIT_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@complicated_args_sret ; IS__TUNIT_OPM-SAME: (%struct.X** nocapture nofree writeonly [[B:%.*]]) #[[ATTR3]] { ; IS__TUNIT_OPM-NEXT: call void @test_sret(%struct.X* noalias nocapture nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 4294967296 null, %struct.X** nocapture nofree writeonly align 8 [[B]]) #[[ATTR12:[0-9]+]] ; IS__TUNIT_OPM-NEXT: ret void ; ; IS__TUNIT_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@complicated_args_sret ; IS__TUNIT_NPM-SAME: (%struct.X** nocapture nofree writeonly [[B:%.*]]) #[[ATTR3]] { ; IS__TUNIT_NPM-NEXT: call void @test_sret(%struct.X* noalias nocapture nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 4294967296 null, %struct.X** nocapture nofree writeonly align 8 [[B]]) #[[ATTR11:[0-9]+]] ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@complicated_args_sret ; IS__CGSCC____-SAME: (%struct.X** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR5:[0-9]+]] { ; IS__CGSCC____-NEXT: unreachable ; call void @test_sret(%struct.X* sret(%struct.X) null, %struct.X** %b) ret void } define internal %struct.X* @test_nest(%struct.X* nest %a) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@test_nest ; IS__CGSCC____-SAME: (%struct.X* nest noalias nocapture nofree readnone align 4294967296 [[A:%.*]]) #[[ATTR1]] { ; IS__CGSCC____-NEXT: ret %struct.X* null ; ret %struct.X* %a } define %struct.X* @complicated_args_nest() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@complicated_args_nest ; IS__TUNIT____-SAME: () #[[ATTR1]] { ; IS__TUNIT____-NEXT: ret %struct.X* null ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_nest ; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias noundef align 4294967296 %struct.X* @test_nest(%struct.X* noalias nocapture nofree noundef readnone align 4294967296 null) #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret %struct.X* [[CALL]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_nest ; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call noalias noundef align 4294967296 %struct.X* @test_nest(%struct.X* noalias nocapture nofree noundef readnone align 4294967296 null) #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret %struct.X* [[CALL]] ; %call = call %struct.X* @test_nest(%struct.X* null) ret %struct.X* %call } @S = external global %struct.X define internal void @test_byval(%struct.X* byval(%struct.X) %a) { ; IS__TUNIT_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test_byval ; IS__TUNIT_OPM-SAME: (%struct.X* noalias nocapture nofree noundef nonnull writeonly byval([[STRUCT_X:%.*]]) align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR3]] { ; IS__TUNIT_OPM-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X]], %struct.X* [[A]], i32 0, i32 0 ; IS__TUNIT_OPM-NEXT: store i8* null, i8** [[G0]], align 8 ; IS__TUNIT_OPM-NEXT: ret void ; ; IS__TUNIT_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test_byval ; IS__TUNIT_NPM-SAME: (i8* [[TMP0:%.*]]) #[[ATTR3]] { ; IS__TUNIT_NPM-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8 ; IS__TUNIT_NPM-NEXT: [[A_PRIV_CAST:%.*]] = bitcast %struct.X* [[A_PRIV]] to i8** ; IS__TUNIT_NPM-NEXT: store i8* [[TMP0]], i8** [[A_PRIV_CAST]], align 8 ; IS__TUNIT_NPM-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X]], %struct.X* [[A_PRIV]], i32 0, i32 0 ; IS__TUNIT_NPM-NEXT: store i8* null, i8** [[G0]], align 8 ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test_byval ; IS__CGSCC_OPM-SAME: (%struct.X* noalias nocapture nofree noundef nonnull writeonly byval([[STRUCT_X:%.*]]) align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR4]] { ; IS__CGSCC_OPM-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X]], %struct.X* [[A]], i32 0, i32 0 ; IS__CGSCC_OPM-NEXT: store i8* null, i8** [[G0]], align 8 ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_byval ; IS__CGSCC_NPM-SAME: (i8* [[TMP0:%.*]]) #[[ATTR4]] { ; IS__CGSCC_NPM-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8 ; IS__CGSCC_NPM-NEXT: [[A_PRIV_CAST:%.*]] = bitcast %struct.X* [[A_PRIV]] to i8** ; IS__CGSCC_NPM-NEXT: store i8* [[TMP0]], i8** [[A_PRIV_CAST]], align 8 ; IS__CGSCC_NPM-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X]], %struct.X* [[A_PRIV]], i32 0, i32 0 ; IS__CGSCC_NPM-NEXT: store i8* null, i8** [[G0]], align 8 ; IS__CGSCC_NPM-NEXT: ret void ; %g0 = getelementptr %struct.X, %struct.X* %a, i32 0, i32 0 store i8* null, i8** %g0 ret void } define void @complicated_args_byval() { ; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@complicated_args_byval ; IS__TUNIT_OPM-SAME: () #[[ATTR4:[0-9]+]] { ; IS__TUNIT_OPM-NEXT: call void @test_byval(%struct.X* nocapture nofree noundef nonnull readonly byval([[STRUCT_X:%.*]]) align 8 dereferenceable(8) @S) #[[ATTR12]] ; IS__TUNIT_OPM-NEXT: ret void ; ; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@complicated_args_byval ; IS__TUNIT_NPM-SAME: () #[[ATTR4:[0-9]+]] { ; IS__TUNIT_NPM-NEXT: [[S_CAST:%.*]] = bitcast %struct.X* @S to i8** ; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i8*, i8** [[S_CAST]], align 8 ; IS__TUNIT_NPM-NEXT: call void @test_byval(i8* [[TMP1]]) #[[ATTR11]] ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_byval ; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: call void @test_byval(%struct.X* noalias nocapture nofree noundef nonnull readnone byval([[STRUCT_X:%.*]]) align 8 dereferenceable(8) @S) #[[ATTR15:[0-9]+]] ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_byval ; IS__CGSCC_NPM-SAME: () #[[ATTR3]] { ; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i8*, i8** getelementptr inbounds ([[STRUCT_X:%.*]], %struct.X* @S, i32 0, i32 0), align 8 ; IS__CGSCC_NPM-NEXT: call void @test_byval(i8* nofree writeonly [[TMP1]]) #[[ATTR14:[0-9]+]] ; IS__CGSCC_NPM-NEXT: ret void ; call void @test_byval(%struct.X* byval(%struct.X) @S) ret void } declare void @sync() ; Make sure we *do not* load @S here! define internal i8*@test_byval2(%struct.X* byval(%struct.X) %a) { ; IS________OPM-LABEL: define {{[^@]+}}@test_byval2 ; IS________OPM-SAME: (%struct.X* noalias nocapture nofree noundef nonnull readonly byval([[STRUCT_X:%.*]]) align 8 dereferenceable(8) [[A:%.*]]) { ; IS________OPM-NEXT: call void @sync() ; IS________OPM-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X]], %struct.X* [[A]], i32 0, i32 0 ; IS________OPM-NEXT: [[L:%.*]] = load i8*, i8** [[G0]], align 8 ; IS________OPM-NEXT: ret i8* [[L]] ; ; IS________NPM-LABEL: define {{[^@]+}}@test_byval2 ; IS________NPM-SAME: (i8* [[TMP0:%.*]]) { ; IS________NPM-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8 ; IS________NPM-NEXT: [[A_PRIV_CAST:%.*]] = bitcast %struct.X* [[A_PRIV]] to i8** ; IS________NPM-NEXT: store i8* [[TMP0]], i8** [[A_PRIV_CAST]], align 8 ; IS________NPM-NEXT: call void @sync() ; IS________NPM-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X]], %struct.X* [[A_PRIV]], i32 0, i32 0 ; IS________NPM-NEXT: [[L:%.*]] = load i8*, i8** [[G0]], align 8 ; IS________NPM-NEXT: ret i8* [[L]] ; call void @sync() %g0 = getelementptr %struct.X, %struct.X* %a, i32 0, i32 0 %l = load i8*, i8** %g0 ret i8* %l } define i8* @complicated_args_byval2() { ; ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@complicated_args_byval2() { ; IS__TUNIT_OPM-NEXT: [[C:%.*]] = call i8* @test_byval2(%struct.X* nocapture nofree noundef nonnull readonly byval([[STRUCT_X:%.*]]) align 8 dereferenceable(8) @S) ; IS__TUNIT_OPM-NEXT: ret i8* [[C]] ; ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@complicated_args_byval2() { ; IS__TUNIT_NPM-NEXT: [[S_CAST:%.*]] = bitcast %struct.X* @S to i8** ; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i8*, i8** [[S_CAST]], align 8 ; IS__TUNIT_NPM-NEXT: [[C:%.*]] = call i8* @test_byval2(i8* [[TMP1]]) ; IS__TUNIT_NPM-NEXT: ret i8* [[C]] ; ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_byval2() { ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i8* @test_byval2(%struct.X* noalias nocapture nofree noundef nonnull readonly byval([[STRUCT_X:%.*]]) align 8 dereferenceable(8) @S) ; IS__CGSCC_OPM-NEXT: ret i8* [[C]] ; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_byval2() { ; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i8*, i8** getelementptr inbounds ([[STRUCT_X:%.*]], %struct.X* @S, i32 0, i32 0), align 8 ; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i8* @test_byval2(i8* [[TMP1]]) ; IS__CGSCC_NPM-NEXT: ret i8* [[C]] ; %c = call i8* @test_byval2(%struct.X* byval(%struct.X) @S) ret i8* %c } define void @fixpoint_changed(i32* %p) { ; IS__TUNIT_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind writeonly ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fixpoint_changed ; IS__TUNIT_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR5:[0-9]+]] { ; IS__TUNIT_OPM-NEXT: entry: ; IS__TUNIT_OPM-NEXT: br label [[FOR_COND:%.*]] ; IS__TUNIT_OPM: for.cond: ; IS__TUNIT_OPM-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[SW_EPILOG:%.*]] ] ; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[J_0]], 30 ; IS__TUNIT_OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] ; IS__TUNIT_OPM: for.body: ; IS__TUNIT_OPM-NEXT: switch i32 [[J_0]], label [[SW_EPILOG]] [ ; IS__TUNIT_OPM-NEXT: i32 1, label [[SW_BB:%.*]] ; IS__TUNIT_OPM-NEXT: ] ; IS__TUNIT_OPM: sw.bb: ; IS__TUNIT_OPM-NEXT: br label [[SW_EPILOG]] ; IS__TUNIT_OPM: sw.epilog: ; IS__TUNIT_OPM-NEXT: [[X_0:%.*]] = phi i32 [ 255, [[FOR_BODY]] ], [ 253, [[SW_BB]] ] ; IS__TUNIT_OPM-NEXT: store i32 [[X_0]], i32* [[P]], align 4 ; IS__TUNIT_OPM-NEXT: [[INC]] = add nsw i32 [[J_0]], 1 ; IS__TUNIT_OPM-NEXT: br label [[FOR_COND]] ; IS__TUNIT_OPM: for.end: ; IS__TUNIT_OPM-NEXT: ret void ; ; IS__TUNIT_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fixpoint_changed ; IS__TUNIT_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR3]] { ; IS__TUNIT_NPM-NEXT: entry: ; IS__TUNIT_NPM-NEXT: br label [[FOR_COND:%.*]] ; IS__TUNIT_NPM: for.cond: ; IS__TUNIT_NPM-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[SW_EPILOG:%.*]] ] ; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[J_0]], 30 ; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] ; IS__TUNIT_NPM: for.body: ; IS__TUNIT_NPM-NEXT: switch i32 [[J_0]], label [[SW_EPILOG]] [ ; IS__TUNIT_NPM-NEXT: i32 1, label [[SW_BB:%.*]] ; IS__TUNIT_NPM-NEXT: ] ; IS__TUNIT_NPM: sw.bb: ; IS__TUNIT_NPM-NEXT: br label [[SW_EPILOG]] ; IS__TUNIT_NPM: sw.epilog: ; IS__TUNIT_NPM-NEXT: [[X_0:%.*]] = phi i32 [ 255, [[FOR_BODY]] ], [ 253, [[SW_BB]] ] ; IS__TUNIT_NPM-NEXT: store i32 [[X_0]], i32* [[P]], align 4 ; IS__TUNIT_NPM-NEXT: [[INC]] = add nsw i32 [[J_0]], 1 ; IS__TUNIT_NPM-NEXT: br label [[FOR_COND]] ; IS__TUNIT_NPM: for.end: ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind writeonly ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fixpoint_changed ; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR6:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: br label [[FOR_COND:%.*]] ; IS__CGSCC_OPM: for.cond: ; IS__CGSCC_OPM-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[SW_EPILOG:%.*]] ] ; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[J_0]], 30 ; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] ; IS__CGSCC_OPM: for.body: ; IS__CGSCC_OPM-NEXT: switch i32 [[J_0]], label [[SW_EPILOG]] [ ; IS__CGSCC_OPM-NEXT: i32 1, label [[SW_BB:%.*]] ; IS__CGSCC_OPM-NEXT: ] ; IS__CGSCC_OPM: sw.bb: ; IS__CGSCC_OPM-NEXT: br label [[SW_EPILOG]] ; IS__CGSCC_OPM: sw.epilog: ; IS__CGSCC_OPM-NEXT: [[X_0:%.*]] = phi i32 [ 255, [[FOR_BODY]] ], [ 253, [[SW_BB]] ] ; IS__CGSCC_OPM-NEXT: store i32 [[X_0]], i32* [[P]], align 4 ; IS__CGSCC_OPM-NEXT: [[INC]] = add nsw i32 [[J_0]], 1 ; IS__CGSCC_OPM-NEXT: br label [[FOR_COND]] ; IS__CGSCC_OPM: for.end: ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fixpoint_changed ; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR4]] { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: br label [[FOR_COND:%.*]] ; IS__CGSCC_NPM: for.cond: ; IS__CGSCC_NPM-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[SW_EPILOG:%.*]] ] ; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[J_0]], 30 ; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] ; IS__CGSCC_NPM: for.body: ; IS__CGSCC_NPM-NEXT: switch i32 [[J_0]], label [[SW_EPILOG]] [ ; IS__CGSCC_NPM-NEXT: i32 1, label [[SW_BB:%.*]] ; IS__CGSCC_NPM-NEXT: ] ; IS__CGSCC_NPM: sw.bb: ; IS__CGSCC_NPM-NEXT: br label [[SW_EPILOG]] ; IS__CGSCC_NPM: sw.epilog: ; IS__CGSCC_NPM-NEXT: [[X_0:%.*]] = phi i32 [ 255, [[FOR_BODY]] ], [ 253, [[SW_BB]] ] ; IS__CGSCC_NPM-NEXT: store i32 [[X_0]], i32* [[P]], align 4 ; IS__CGSCC_NPM-NEXT: [[INC]] = add nsw i32 [[J_0]], 1 ; IS__CGSCC_NPM-NEXT: br label [[FOR_COND]] ; IS__CGSCC_NPM: for.end: ; IS__CGSCC_NPM-NEXT: ret void ; entry: br label %for.cond for.cond: %j.0 = phi i32 [ 0, %entry ], [ %inc, %sw.epilog ] %cmp = icmp slt i32 %j.0, 30 br i1 %cmp, label %for.body, label %for.end for.body: switch i32 %j.0, label %sw.epilog [ i32 1, label %sw.bb ] sw.bb: br label %sw.epilog sw.epilog: %x.0 = phi i32 [ 255, %for.body ], [ 253, %sw.bb ] store i32 %x.0, i32* %p %inc = add nsw i32 %j.0, 1 br label %for.cond for.end: ret void } ; Check we merge undef and a constant properly. define i8 @caller0() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@caller0 ; IS__TUNIT____-SAME: () #[[ATTR1]] { ; IS__TUNIT____-NEXT: ret i8 49 ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller0 ; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret i8 [[C]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller0 ; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret i8 [[C]] ; %c = call i8 @callee(i8 undef) ret i8 %c } define i8 @caller1() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@caller1 ; IS__TUNIT____-SAME: () #[[ATTR1]] { ; IS__TUNIT____-NEXT: ret i8 49 ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller1 ; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret i8 [[C]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller1 ; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret i8 [[C]] ; %c = call i8 @callee(i8 undef) ret i8 %c } define i8 @caller2() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@caller2 ; IS__TUNIT____-SAME: () #[[ATTR1]] { ; IS__TUNIT____-NEXT: ret i8 49 ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller2 ; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret i8 [[C]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller2 ; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret i8 [[C]] ; %c = call i8 @callee(i8 undef) ret i8 %c } define i8 @caller_middle() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@caller_middle ; IS__TUNIT____-SAME: () #[[ATTR1]] { ; IS__TUNIT____-NEXT: ret i8 49 ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller_middle ; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret i8 [[C]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller_middle ; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret i8 [[C]] ; %c = call i8 @callee(i8 42) ret i8 %c } define i8 @caller3() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@caller3 ; IS__TUNIT____-SAME: () #[[ATTR1]] { ; IS__TUNIT____-NEXT: ret i8 49 ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller3 ; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret i8 [[C]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller3 ; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret i8 [[C]] ; %c = call i8 @callee(i8 undef) ret i8 %c } define i8 @caller4() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@caller4 ; IS__TUNIT____-SAME: () #[[ATTR1]] { ; IS__TUNIT____-NEXT: ret i8 49 ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller4 ; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret i8 [[C]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller4 ; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret i8 [[C]] ; %c = call i8 @callee(i8 undef) ret i8 %c } define internal i8 @callee(i8 %a) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@callee ; IS__CGSCC____-SAME: () #[[ATTR1]] { ; IS__CGSCC____-NEXT: ret i8 49 ; %c = add i8 %a, 7 ret i8 %c } define void @user_as3() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; IS__TUNIT____-LABEL: define {{[^@]+}}@user_as3 ; IS__TUNIT____-SAME: () #[[ATTR4:[0-9]+]] { ; IS__TUNIT____-NEXT: store i32 0, i32 addrspace(3)* @ConstAS3Ptr, align 4 ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind willreturn writeonly ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@user_as3 ; IS__CGSCC_OPM-SAME: () #[[ATTR7:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call fastcc align 4 i32 addrspace(3)* @const_ptr_return_as3() #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: store i32 0, i32 addrspace(3)* [[CALL]], align 4 ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn writeonly ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@user_as3 ; IS__CGSCC_NPM-SAME: () #[[ATTR6:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call fastcc align 4 i32 addrspace(3)* @const_ptr_return_as3() #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: store i32 0, i32 addrspace(3)* [[CALL]], align 4 ; IS__CGSCC_NPM-NEXT: ret void ; %call = call fastcc i32 addrspace(3)* @const_ptr_return_as3() store i32 0, i32 addrspace(3)* %call ret void } define void @user() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; IS__TUNIT____-LABEL: define {{[^@]+}}@user ; IS__TUNIT____-SAME: () #[[ATTR4]] { ; IS__TUNIT____-NEXT: store i32 0, i32* addrspacecast (i32 addrspace(3)* @ConstAS3Ptr to i32*), align 4 ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind willreturn writeonly ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@user ; IS__CGSCC_OPM-SAME: () #[[ATTR7]] { ; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call fastcc align 4 i32* @const_ptr_return() #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[CALL]], align 4 ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn writeonly ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@user ; IS__CGSCC_NPM-SAME: () #[[ATTR6]] { ; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call fastcc align 4 i32* @const_ptr_return() #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: store i32 0, i32* [[CALL]], align 4 ; IS__CGSCC_NPM-NEXT: ret void ; %call = call fastcc i32* @const_ptr_return() store i32 0, i32* %call ret void } define i1 @test_merge_with_undef_values_ptr(i1 %c) { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; IS__TUNIT____-NEXT: ret i1 false ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr ; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call noundef i1 @undef_then_null(i1 [[C]]) #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret i1 [[R1]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr ; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: [[R1:%.*]] = call noundef i1 @undef_then_null(i1 [[C]]) #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret i1 [[R1]] ; %r1 = call i1 @undef_then_null(i1 %c, i32* undef, i32* undef) ret i1 %r1 } define internal i1 @undef_then_null(i1 %c, i32* %i32Aptr, i32* %i32Bptr) { ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@undef_then_null ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] { ; IS__CGSCC____-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] ; IS__CGSCC____: a: ; IS__CGSCC____-NEXT: ret i1 false ; IS__CGSCC____: b: ; IS__CGSCC____-NEXT: ret i1 false ; %cmp1 = icmp eq i32* %i32Aptr, %i32Bptr %cmp2 = icmp eq i1 %cmp1, false %or = or i1 %cmp2, %c br i1 %or, label %a, label %b a: %r2 = call i1 @undef_then_null(i1 false, i32* null, i32* null) ret i1 %r2 b: ret i1 %cmp2 } define i1 @test_merge_with_undef_values(i1 %c) { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@test_merge_with_undef_values ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; IS__TUNIT____-NEXT: ret i1 false ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test_merge_with_undef_values ; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call noundef i1 @undef_then_1(i1 [[C]]) #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret i1 [[R1]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_merge_with_undef_values ; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: [[R1:%.*]] = call noundef i1 @undef_then_1(i1 [[C]]) #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret i1 [[R1]] ; %r1 = call i1 @undef_then_1(i1 %c, i32 undef, i32 undef) ret i1 %r1 } define internal i1 @undef_then_1(i1 %c, i32 %i32A, i32 %i32B) { ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@undef_then_1 ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC____-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] ; IS__CGSCC____: a: ; IS__CGSCC____-NEXT: ret i1 false ; IS__CGSCC____: b: ; IS__CGSCC____-NEXT: ret i1 false ; %cmp1 = icmp eq i32 %i32A, %i32B %cmp2 = icmp eq i1 %cmp1, false %or = or i1 %cmp2, %c br i1 %or, label %a, label %b a: %r2 = call i1 @undef_then_1(i1 false, i32 1, i32 1) ret i1 %r2 b: ret i1 %cmp2 } define i32 @test_select(i32 %c) { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@test_select ; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { ; IS__TUNIT____-NEXT: ret i32 42 ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test_select ; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noundef i32 @select() #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret i32 [[CALL]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_select ; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call noundef i32 @select() #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret i32 [[CALL]] ; %call = call i32 @select(i1 1, i32 42, i32 %c) ret i32 %call } define internal i32 @select(i1 %a, i32 %b, i32 %c) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@select ; IS__CGSCC____-SAME: () #[[ATTR1]] { ; IS__CGSCC____-NEXT: ret i32 42 ; %s = select i1 %a, i32 %b, i32 %c ret i32 %s } define i1 @icmp() { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@icmp ; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: ret i1 true ; %c = icmp eq i8* null, null ret i1 %c } define void @test_callee_is_undef(void (i32)* %fn) { ; IS__TUNIT____-LABEL: define {{[^@]+}}@test_callee_is_undef ; IS__TUNIT____-SAME: (void (i32)* nocapture nofree [[FN:%.*]]) { ; IS__TUNIT____-NEXT: call void @callee_is_undef() ; IS__TUNIT____-NEXT: call void @unknown_calle_arg_is_undef(void (i32)* nocapture nofree [[FN]]) ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____-LABEL: define {{[^@]+}}@test_callee_is_undef ; IS__CGSCC____-SAME: (void (i32)* nocapture nofree [[FN:%.*]]) { ; IS__CGSCC____-NEXT: call void @callee_is_undef() ; IS__CGSCC____-NEXT: call void @unknown_calle_arg_is_undef(void (i32)* nocapture nofree noundef nonnull [[FN]]) ; IS__CGSCC____-NEXT: ret void ; call void @callee_is_undef(void ()* undef) call void @unknown_calle_arg_is_undef(void (i32)* %fn, i32 undef) ret void } define internal void @callee_is_undef(void ()* %fn) { ; ; CHECK-LABEL: define {{[^@]+}}@callee_is_undef() { ; CHECK-NEXT: call void poison() ; CHECK-NEXT: ret void ; call void %fn() ret void } define internal void @unknown_calle_arg_is_undef(void (i32)* %fn, i32 %arg) { ; ; CHECK-LABEL: define {{[^@]+}}@unknown_calle_arg_is_undef ; CHECK-SAME: (void (i32)* nocapture nofree noundef nonnull [[FN:%.*]]) { ; CHECK-NEXT: call void [[FN]](i32 undef) ; CHECK-NEXT: ret void ; call void %fn(i32 %arg) ret void } ; Taken from 50683 ; {{{ @g = internal constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (void (i8***)* @f1 to i8*), i8* bitcast (void (i1 (i8*)*)* @f2 to i8*)] } define internal void @f1(i8*** %a) { ; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__TUNIT____-LABEL: define {{[^@]+}}@f1 ; IS__TUNIT____-SAME: (i8*** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR3]] { ; IS__TUNIT____-NEXT: entry: ; IS__TUNIT____-NEXT: store i8** getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @g, i32 0, i32 0, i32 0), i8*** [[A]], align 8 ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@f1 ; IS__CGSCC____-SAME: (i8*** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR4]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: store i8** getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @g, i32 0, i32 0, i32 0), i8*** [[A]], align 8 ; IS__CGSCC____-NEXT: ret void ; entry: %x = getelementptr { [2 x i8*] }, { [2 x i8*] }* @g, i32 0, i32 0, i32 0 store i8** %x , i8*** %a, align 8 ret void } define internal void @f2(i1 (i8*)* %a) { ; CHECK-LABEL: define {{[^@]+}}@f2 ; CHECK-SAME: (i1 (i8*)* [[A:%.*]]) { ; CHECK-NEXT: cont461: ; CHECK-NEXT: [[C1:%.*]] = bitcast i1 (i8*)* [[A]] to i8* ; CHECK-NEXT: call void @f3(i8* [[C1]], i1 (i8*)* nocapture nofree [[A]]) ; CHECK-NEXT: ret void ; cont461: %c1 = bitcast i1 (i8*)* %a to i8* call void @f3(i8* %c1, i1 (i8*)* %a) ret void } define internal void @f3(i8* %a1, i1 (i8*)* %a) { ; CHECK-LABEL: define {{[^@]+}}@f3 ; CHECK-SAME: (i8* [[A1:%.*]], i1 (i8*)* nocapture nofree [[A:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CALL20:%.*]] = call i1 @f9() ; CHECK-NEXT: br i1 [[CALL20]], label [[LAND_LHS_TRUE:%.*]], label [[IF_END40:%.*]] ; CHECK: land.lhs.true: ; CHECK-NEXT: [[TMP0:%.*]] = call i1 [[A]](i8* [[A1]]) ; CHECK-NEXT: br label [[IF_END40]] ; CHECK: if.end40: ; CHECK-NEXT: ret void ; entry: %call20 = call i1 @f9() br i1 %call20, label %land.lhs.true, label %if.end40 land.lhs.true: call i1 %a(i8* %a1) br label %if.end40 if.end40: ret void } define linkonce_odr i1 @f9() { ; CHECK-LABEL: define {{[^@]+}}@f9() { ; CHECK-NEXT: entry: ; CHECK-NEXT: ret i1 false ; entry: ret i1 false } ; }}} define i1 @test_cmp_null_after_cast() { ; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@test_cmp_null_after_cast ; IS__TUNIT____-SAME: () #[[ATTR1]] { ; IS__TUNIT____-NEXT: ret i1 true ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test_cmp_null_after_cast ; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i1 @cmp_null_after_cast() #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret i1 [[C]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_cmp_null_after_cast ; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i1 @cmp_null_after_cast() #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret i1 [[C]] ; %c = call i1 @cmp_null_after_cast(i32 0, i8 0) ret i1 %c } define internal i1 @cmp_null_after_cast(i32 %a, i8 %b) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@cmp_null_after_cast ; IS__CGSCC____-SAME: () #[[ATTR1]] { ; IS__CGSCC____-NEXT: ret i1 true ; %t = trunc i32 %a to i8 %c = icmp eq i8 %t, %b ret i1 %c } declare i8* @m() define i32 @test(i1 %c) { ; CHECK-LABEL: define {{[^@]+}}@test ; CHECK-SAME: (i1 [[C:%.*]]) { ; CHECK-NEXT: [[R1:%.*]] = call i32 @ctx_test1(i1 [[C]]) ; CHECK-NEXT: [[R2:%.*]] = call i32 @ctx_test2(i1 [[C]]) ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[R1]], [[R2]] ; CHECK-NEXT: ret i32 [[ADD]] ; %r1 = call i32 @ctx_test1(i1 %c) %r2 = call i32 @ctx_test2(i1 %c) %add = add i32 %r1, %r2 ret i32 %add } define internal i32 @ctx_test1(i1 %c) { ; CHECK-LABEL: define {{[^@]+}}@ctx_test1 ; CHECK-SAME: (i1 [[C:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[JOIN:%.*]] ; CHECK: then: ; CHECK-NEXT: [[M:%.*]] = tail call i8* @m() ; CHECK-NEXT: [[I:%.*]] = ptrtoint i8* [[M]] to i64 ; CHECK-NEXT: br label [[JOIN]] ; CHECK: join: ; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ [[I]], [[THEN]] ], [ undef, [[ENTRY:%.*]] ] ; CHECK-NEXT: [[RET:%.*]] = trunc i64 [[PHI]] to i32 ; CHECK-NEXT: ret i32 [[RET]] ; entry: br i1 %c, label %then, label %join then: %m = tail call i8* @m() %i = ptrtoint i8* %m to i64 br label %join join: %phi = phi i64 [ %i, %then ], [ undef, %entry ] %ret = trunc i64 %phi to i32 ret i32 %ret } define internal i32 @ctx_test2(i1 %c) { ; CHECK-LABEL: define {{[^@]+}}@ctx_test2 ; CHECK-SAME: (i1 [[C:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[JOIN:%.*]] ; CHECK: then: ; CHECK-NEXT: [[M:%.*]] = tail call i8* @m() ; CHECK-NEXT: [[I:%.*]] = ptrtoint i8* [[M]] to i32 ; CHECK-NEXT: br label [[JOIN]] ; CHECK: join: ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[I]], [[THEN]] ], [ undef, [[ENTRY:%.*]] ] ; CHECK-NEXT: [[RET:%.*]] = lshr i32 [[PHI]], 1 ; CHECK-NEXT: ret i32 [[RET]] ; entry: br i1 %c, label %then, label %join then: %m = tail call i8* @m() %i = ptrtoint i8* %m to i32 br label %join join: %phi = phi i32 [ %i, %then ], [ undef, %entry ] %ret = lshr i32 %phi, 1 ret i32 %ret uselistorder label %join, { 1, 0 } } define i1 @test_liveness(i1 %c) { ; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test_liveness ; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; IS__TUNIT_OPM-NEXT: entry: ; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__TUNIT_OPM: t: ; IS__TUNIT_OPM-NEXT: br label [[F]] ; IS__TUNIT_OPM: f: ; IS__TUNIT_OPM-NEXT: [[P:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[T]] ] ; IS__TUNIT_OPM-NEXT: [[RC1:%.*]] = call i1 @ret(i1 noundef [[P]]) #[[ATTR10]] ; IS__TUNIT_OPM-NEXT: ret i1 [[RC1]] ; ; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test_liveness ; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { ; IS__TUNIT_NPM-NEXT: entry: ; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__TUNIT_NPM: t: ; IS__TUNIT_NPM-NEXT: br label [[F]] ; IS__TUNIT_NPM: f: ; IS__TUNIT_NPM-NEXT: [[P:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[T]] ] ; IS__TUNIT_NPM-NEXT: [[RC1:%.*]] = call i1 @ret(i1 noundef [[P]]) #[[ATTR9]] ; IS__TUNIT_NPM-NEXT: ret i1 [[RC1]] ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test_liveness ; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC_OPM: t: ; IS__CGSCC_OPM-NEXT: br label [[F]] ; IS__CGSCC_OPM: f: ; IS__CGSCC_OPM-NEXT: [[P:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[T]] ] ; IS__CGSCC_OPM-NEXT: [[RC1:%.*]] = call noundef i1 @ret(i1 noundef [[P]]) #[[ATTR13]] ; IS__CGSCC_OPM-NEXT: ret i1 [[RC1]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_liveness ; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC_NPM: t: ; IS__CGSCC_NPM-NEXT: br label [[F]] ; IS__CGSCC_NPM: f: ; IS__CGSCC_NPM-NEXT: [[P:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[T]] ] ; IS__CGSCC_NPM-NEXT: [[RC1:%.*]] = call noundef i1 @ret(i1 noundef [[P]]) #[[ATTR12]] ; IS__CGSCC_NPM-NEXT: ret i1 [[RC1]] ; entry: br i1 %c, label %t, label %f t: br label %f f: %p = phi i1 [true, %entry], [false, %t] %rc1 = call i1 @ret(i1 %p) ret i1 %rc1 } define internal i1 @ret(i1 %c) { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@ret ; CHECK-SAME: (i1 noundef [[C:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; CHECK: t: ; CHECK-NEXT: br label [[F]] ; CHECK: f: ; CHECK-NEXT: [[P:%.*]] = phi i1 [ [[C]], [[ENTRY:%.*]] ], [ false, [[T]] ] ; CHECK-NEXT: ret i1 [[P]] ; entry: br i1 %c, label %t, label %f t: br label %f f: %p = phi i1 [%c, %entry], [false, %t] ret i1 %p } declare i8* @unknown() define internal i8 @dead_ret() { ; CHECK-LABEL: define {{[^@]+}}@dead_ret() { ; CHECK-NEXT: [[R:%.*]] = call i8* @unknown() ; CHECK-NEXT: ret i8 undef ; %r = call i8* @unknown() %l = load i8, i8* %r ret i8 %l } define void @dead_ret_caller() { ; CHECK-LABEL: define {{[^@]+}}@dead_ret_caller() { ; CHECK-NEXT: [[R:%.*]] = call i8 @dead_ret() ; CHECK-NEXT: ret void ; %r = call i8 @dead_ret() ret void } declare void @llvm.memcpy(i8* %dest, i8* %src, i32 %len, i1 %isvolatile) define internal i8 @memcpy_uses_store(i8 %arg) { ; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@memcpy_uses_store ; IS__TUNIT_OPM-SAME: (i8 [[ARG:%.*]]) #[[ATTR2]] { ; IS__TUNIT_OPM-NEXT: [[SRC:%.*]] = alloca i8, align 1 ; IS__TUNIT_OPM-NEXT: [[DST:%.*]] = alloca i8, align 1 ; IS__TUNIT_OPM-NEXT: store i8 [[ARG]], i8* [[SRC]], align 1 ; IS__TUNIT_OPM-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[DST]], i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR11]] ; IS__TUNIT_OPM-NEXT: [[L:%.*]] = load i8, i8* [[DST]], align 1 ; IS__TUNIT_OPM-NEXT: ret i8 [[L]] ; ; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@memcpy_uses_store ; IS__TUNIT_NPM-SAME: (i8 [[ARG:%.*]]) #[[ATTR2]] { ; IS__TUNIT_NPM-NEXT: [[SRC:%.*]] = alloca i8, align 1 ; IS__TUNIT_NPM-NEXT: [[DST:%.*]] = alloca i8, align 1 ; IS__TUNIT_NPM-NEXT: store i8 [[ARG]], i8* [[SRC]], align 1 ; IS__TUNIT_NPM-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[DST]], i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR10]] ; IS__TUNIT_NPM-NEXT: [[L:%.*]] = load i8, i8* [[DST]], align 1 ; IS__TUNIT_NPM-NEXT: ret i8 [[L]] ; ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@memcpy_uses_store ; IS__CGSCC_OPM-SAME: (i8 [[ARG:%.*]]) #[[ATTR8:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: [[SRC:%.*]] = alloca i8, align 1 ; IS__CGSCC_OPM-NEXT: [[DST:%.*]] = alloca i8, align 1 ; IS__CGSCC_OPM-NEXT: store i8 [[ARG]], i8* [[SRC]], align 1 ; IS__CGSCC_OPM-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[DST]], i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR14]] ; IS__CGSCC_OPM-NEXT: [[L:%.*]] = load i8, i8* [[DST]], align 1 ; IS__CGSCC_OPM-NEXT: ret i8 [[L]] ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@memcpy_uses_store ; IS__CGSCC_NPM-SAME: (i8 [[ARG:%.*]]) #[[ATTR7:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: [[SRC:%.*]] = alloca i8, align 1 ; IS__CGSCC_NPM-NEXT: [[DST:%.*]] = alloca i8, align 1 ; IS__CGSCC_NPM-NEXT: store i8 [[ARG]], i8* [[SRC]], align 1 ; IS__CGSCC_NPM-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[DST]], i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR13]] ; IS__CGSCC_NPM-NEXT: [[L:%.*]] = load i8, i8* [[DST]], align 1 ; IS__CGSCC_NPM-NEXT: ret i8 [[L]] ; %src = alloca i8 %dst = alloca i8 store i8 %arg, i8* %src call void @llvm.memcpy(i8* %dst, i8* %src, i32 1, i1 false) %l = load i8, i8* %dst ret i8 %l } define i8 @memcpy_uses_store_caller(i8 %arg) { ; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@memcpy_uses_store_caller ; IS__TUNIT_OPM-SAME: (i8 [[ARG:%.*]]) #[[ATTR2]] { ; IS__TUNIT_OPM-NEXT: [[R:%.*]] = call i8 @memcpy_uses_store(i8 [[ARG]]) #[[ATTR13:[0-9]+]] ; IS__TUNIT_OPM-NEXT: ret i8 [[R]] ; ; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@memcpy_uses_store_caller ; IS__TUNIT_NPM-SAME: (i8 [[ARG:%.*]]) #[[ATTR2]] { ; IS__TUNIT_NPM-NEXT: [[R:%.*]] = call i8 @memcpy_uses_store(i8 [[ARG]]) #[[ATTR12:[0-9]+]] ; IS__TUNIT_NPM-NEXT: ret i8 [[R]] ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@memcpy_uses_store_caller ; IS__CGSCC_OPM-SAME: (i8 [[ARG:%.*]]) #[[ATTR3]] { ; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i8 @memcpy_uses_store(i8 [[ARG]]) #[[ATTR16:[0-9]+]] ; IS__CGSCC_OPM-NEXT: ret i8 [[R]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@memcpy_uses_store_caller ; IS__CGSCC_NPM-SAME: (i8 [[ARG:%.*]]) #[[ATTR3]] { ; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call i8 @memcpy_uses_store(i8 [[ARG]]) #[[ATTR15:[0-9]+]] ; IS__CGSCC_NPM-NEXT: ret i8 [[R]] ; %r = call i8 @memcpy_uses_store(i8 %arg) ret i8 %r } declare i32 @speculatable() speculatable readnone define i32 @test_speculatable_expr() norecurse { ; IS__TUNIT_OPM: Function Attrs: norecurse nosync readnone ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test_speculatable_expr ; IS__TUNIT_OPM-SAME: () #[[ATTR7:[0-9]+]] { ; IS__TUNIT_OPM-NEXT: [[STACK:%.*]] = alloca i32, align 4 ; IS__TUNIT_OPM-NEXT: [[SPEC_RESULT:%.*]] = call i32 @speculatable() ; IS__TUNIT_OPM-NEXT: [[PLUS1:%.*]] = add i32 [[SPEC_RESULT]], 1 ; IS__TUNIT_OPM-NEXT: store i32 [[PLUS1]], i32* [[STACK]], align 4 ; IS__TUNIT_OPM-NEXT: [[RSPEC:%.*]] = call i32 @ret_speculatable_expr(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[STACK]]) #[[ATTR14:[0-9]+]] ; IS__TUNIT_OPM-NEXT: ret i32 [[RSPEC]] ; ; IS__TUNIT_NPM: Function Attrs: norecurse nosync readnone ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test_speculatable_expr ; IS__TUNIT_NPM-SAME: () #[[ATTR6:[0-9]+]] { ; IS__TUNIT_NPM-NEXT: [[STACK:%.*]] = alloca i32, align 4 ; IS__TUNIT_NPM-NEXT: [[SPEC_RESULT:%.*]] = call i32 @speculatable() ; IS__TUNIT_NPM-NEXT: [[PLUS1:%.*]] = add i32 [[SPEC_RESULT]], 1 ; IS__TUNIT_NPM-NEXT: store i32 [[PLUS1]], i32* [[STACK]], align 4 ; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[STACK]], align 4 ; IS__TUNIT_NPM-NEXT: [[RSPEC:%.*]] = call i32 @ret_speculatable_expr(i32 [[TMP1]]) #[[ATTR13:[0-9]+]] ; IS__TUNIT_NPM-NEXT: ret i32 [[RSPEC]] ; ; IS__CGSCC_OPM: Function Attrs: norecurse nosync readnone ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test_speculatable_expr ; IS__CGSCC_OPM-SAME: () #[[ATTR10:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: [[STACK:%.*]] = alloca i32, align 4 ; IS__CGSCC_OPM-NEXT: [[SPEC_RESULT:%.*]] = call i32 @speculatable() ; IS__CGSCC_OPM-NEXT: [[PLUS1:%.*]] = add i32 [[SPEC_RESULT]], 1 ; IS__CGSCC_OPM-NEXT: store i32 [[PLUS1]], i32* [[STACK]], align 4 ; IS__CGSCC_OPM-NEXT: [[RSPEC:%.*]] = call i32 @ret_speculatable_expr(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[STACK]]) #[[ATTR17:[0-9]+]] ; IS__CGSCC_OPM-NEXT: ret i32 [[RSPEC]] ; ; IS__CGSCC_NPM: Function Attrs: norecurse nosync readnone ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_speculatable_expr ; IS__CGSCC_NPM-SAME: () #[[ATTR9:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: [[STACK:%.*]] = alloca i32, align 4 ; IS__CGSCC_NPM-NEXT: [[SPEC_RESULT:%.*]] = call i32 @speculatable() ; IS__CGSCC_NPM-NEXT: [[PLUS1:%.*]] = add i32 [[SPEC_RESULT]], 1 ; IS__CGSCC_NPM-NEXT: store i32 [[PLUS1]], i32* [[STACK]], align 4 ; IS__CGSCC_NPM-NEXT: [[RSPEC:%.*]] = call i32 @ret_speculatable_expr(i32 [[PLUS1]]) ; IS__CGSCC_NPM-NEXT: ret i32 [[RSPEC]] ; %stack = alloca i32 %spec_result = call i32 @speculatable() %plus1 = add i32 %spec_result, 1 store i32 %plus1, i32* %stack %rspec = call i32 @ret_speculatable_expr(i32* %stack, i32 13) ret i32 %rspec } define internal i32 @ret_speculatable_expr(i32* %mem, i32 %a2) { ; IS__TUNIT_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@ret_speculatable_expr ; IS__TUNIT_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[MEM:%.*]]) #[[ATTR8:[0-9]+]] { ; IS__TUNIT_OPM-NEXT: [[L:%.*]] = load i32, i32* [[MEM]], align 4 ; IS__TUNIT_OPM-NEXT: [[MUL:%.*]] = mul i32 [[L]], 13 ; IS__TUNIT_OPM-NEXT: [[ADD:%.*]] = add i32 [[MUL]], 7 ; IS__TUNIT_OPM-NEXT: ret i32 [[ADD]] ; ; IS__TUNIT_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@ret_speculatable_expr ; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR7:[0-9]+]] { ; IS__TUNIT_NPM-NEXT: [[MEM_PRIV:%.*]] = alloca i32, align 4 ; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[MEM_PRIV]], align 4 ; IS__TUNIT_NPM-NEXT: [[L:%.*]] = load i32, i32* [[MEM_PRIV]], align 4 ; IS__TUNIT_NPM-NEXT: [[MUL:%.*]] = mul i32 [[L]], 13 ; IS__TUNIT_NPM-NEXT: [[ADD:%.*]] = add i32 [[MUL]], 7 ; IS__TUNIT_NPM-NEXT: ret i32 [[ADD]] ; ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ret_speculatable_expr ; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[MEM:%.*]]) #[[ATTR11:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: [[L:%.*]] = load i32, i32* [[MEM]], align 4 ; IS__CGSCC_OPM-NEXT: [[MUL:%.*]] = mul i32 [[L]], 13 ; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = add i32 [[MUL]], 7 ; IS__CGSCC_OPM-NEXT: ret i32 [[ADD]] ; ; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ret_speculatable_expr ; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR10:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: [[MEM_PRIV:%.*]] = alloca i32, align 4 ; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[MEM_PRIV]], align 4 ; IS__CGSCC_NPM-NEXT: [[L:%.*]] = load i32, i32* [[MEM_PRIV]], align 4 ; IS__CGSCC_NPM-NEXT: [[MUL:%.*]] = mul i32 [[L]], 13 ; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = add i32 [[MUL]], 7 ; IS__CGSCC_NPM-NEXT: ret i32 [[ADD]] ; %l = load i32, i32* %mem %mul = mul i32 %l, %a2 %add = add i32 %mul, 7 ret i32 %add } ;. ; IS__TUNIT_OPM: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } ; IS__TUNIT_OPM: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn writeonly } ; IS__TUNIT_OPM: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind writeonly } ; IS__TUNIT_OPM: attributes #[[ATTR6:[0-9]+]] = { readnone speculatable } ; IS__TUNIT_OPM: attributes #[[ATTR7]] = { norecurse nosync readnone } ; IS__TUNIT_OPM: attributes #[[ATTR8]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR9:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR10]] = { nofree nosync nounwind readnone willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR11]] = { willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR12]] = { nofree nosync nounwind willreturn writeonly } ; IS__TUNIT_OPM: attributes #[[ATTR13]] = { nofree nosync nounwind willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR14]] = { nosync nounwind readonly } ;. ; IS__TUNIT_NPM: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } ; IS__TUNIT_NPM: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn writeonly } ; IS__TUNIT_NPM: attributes #[[ATTR5:[0-9]+]] = { readnone speculatable } ; IS__TUNIT_NPM: attributes #[[ATTR6]] = { norecurse nosync readnone } ; IS__TUNIT_NPM: attributes #[[ATTR7]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR8:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR9]] = { nofree nosync nounwind readnone willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR10]] = { willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR11]] = { nofree nosync nounwind willreturn writeonly } ; IS__TUNIT_NPM: attributes #[[ATTR12]] = { nofree nosync nounwind willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR13]] = { nosync nounwind readonly } ;. ; IS__CGSCC_OPM: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } ; IS__CGSCC_OPM: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind willreturn writeonly } ; IS__CGSCC_OPM: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind writeonly } ; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nofree nosync nounwind willreturn writeonly } ; IS__CGSCC_OPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR9:[0-9]+]] = { readnone speculatable } ; IS__CGSCC_OPM: attributes #[[ATTR10]] = { norecurse nosync readnone } ; IS__CGSCC_OPM: attributes #[[ATTR11]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR12:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR13]] = { readnone willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR14]] = { willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR15]] = { nounwind willreturn writeonly } ; IS__CGSCC_OPM: attributes #[[ATTR16]] = { nounwind willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR17]] = { readonly } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } ; IS__CGSCC_NPM: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind willreturn writeonly } ; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nofree nosync nounwind willreturn writeonly } ; IS__CGSCC_NPM: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR8:[0-9]+]] = { readnone speculatable } ; IS__CGSCC_NPM: attributes #[[ATTR9]] = { norecurse nosync readnone } ; IS__CGSCC_NPM: attributes #[[ATTR10]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR11:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR12]] = { readnone willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR13]] = { willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR14]] = { nounwind willreturn writeonly } ; IS__CGSCC_NPM: attributes #[[ATTR15]] = { nounwind willreturn } ;.