1712 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals2; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT3; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC4 5target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"6declare void @f(i32)7declare token @llvm.call.preallocated.setup(i32)8declare ptr @llvm.call.preallocated.arg(token, i32)9 10@str = private unnamed_addr addrspace(4) constant [1 x i8] c"\00", align 111@ConstAS3Ptr = addrspace(3) global i32 0, align 412@ConstPtr = constant i32 0, align 413@ConstWeakPtr = weak constant i32 0, align 414@ConstWeakODRPtr = weak_odr constant i32 0, align 415@ExtInitZeroInit = externally_initialized constant i32 zeroinitializer, align 416 17;.18; CHECK: @str = private unnamed_addr addrspace(4) constant [1 x i8] zeroinitializer, align 119; CHECK: @ConstAS3Ptr = addrspace(3) global i32 0, align 420; CHECK: @ConstPtr = constant i32 0, align 421; CHECK: @ConstWeakPtr = weak constant i32 0, align 422; CHECK: @ConstWeakODRPtr = weak_odr constant i32 0, align 423; CHECK: @ExtInitZeroInit = externally_initialized constant i32 0, align 424; CHECK: @S = external global %struct.X25; CHECK: @g = internal constant { [2 x ptr] } { [2 x ptr] [ptr @f1, ptr @f2] }26; CHECK: @x = external global i3227;.28define internal ptr addrspace(3) @const_ptr_return_as3() {29; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)30; CGSCC-LABEL: define {{[^@]+}}@const_ptr_return_as331; CGSCC-SAME: () #[[ATTR1:[0-9]+]] {32; CGSCC-NEXT: ret ptr addrspace(3) @ConstAS3Ptr33;34 ret ptr addrspace(3) @ConstAS3Ptr35}36define internal ptr @const_ptr_return() {37; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)38; CGSCC-LABEL: define {{[^@]+}}@const_ptr_return39; CGSCC-SAME: () #[[ATTR1]] {40; CGSCC-NEXT: ret ptr addrspacecast (ptr addrspace(3) @ConstAS3Ptr to ptr)41;42 ret ptr addrspacecast (ptr addrspace(3) @ConstAS3Ptr to ptr)43}44 45; Test1: Replace argument with constant46define internal void @test1(i32 %a) {47; TUNIT: Function Attrs: memory(readwrite, argmem: none)48; TUNIT-LABEL: define {{[^@]+}}@test149; TUNIT-SAME: () #[[ATTR1:[0-9]+]] {50; TUNIT-NEXT: tail call void @f(i32 noundef 1)51; TUNIT-NEXT: ret void52;53; CGSCC: Function Attrs: memory(readwrite, argmem: none)54; CGSCC-LABEL: define {{[^@]+}}@test155; CGSCC-SAME: () #[[ATTR2:[0-9]+]] {56; CGSCC-NEXT: tail call void @f(i32 noundef 1)57; CGSCC-NEXT: ret void58;59 tail call void @f(i32 %a)60 ret void61}62 63define void @test1_helper() {64; CHECK-LABEL: define {{[^@]+}}@test1_helper() {65; CHECK-NEXT: tail call void @test1()66; CHECK-NEXT: ret void67;68 tail call void @test1(i32 1)69 ret void70}71 72; TEST 2 : Simplify return value73define i32 @return0() {74; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)75; TUNIT-LABEL: define {{[^@]+}}@return076; TUNIT-SAME: () #[[ATTR2:[0-9]+]] {77; TUNIT-NEXT: ret i32 078;79; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)80; CGSCC-LABEL: define {{[^@]+}}@return081; CGSCC-SAME: () #[[ATTR1]] {82; CGSCC-NEXT: ret i32 083;84 ret i32 085}86 87define i32 @return1() {88; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)89; TUNIT-LABEL: define {{[^@]+}}@return190; TUNIT-SAME: () #[[ATTR2]] {91; TUNIT-NEXT: ret i32 192;93; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)94; CGSCC-LABEL: define {{[^@]+}}@return195; CGSCC-SAME: () #[[ATTR1]] {96; CGSCC-NEXT: ret i32 197;98 ret i32 199}100 101define i32 @test2_1(i1 %c) {102; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)103; TUNIT-LABEL: define {{[^@]+}}@test2_1104; TUNIT-SAME: (i1 noundef [[C:%.*]]) #[[ATTR2]] {105; TUNIT-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]106; TUNIT: if.true:107; TUNIT-NEXT: [[RET0:%.*]] = add i32 0, 1108; TUNIT-NEXT: br label [[END:%.*]]109; TUNIT: if.false:110; TUNIT-NEXT: br label [[END]]111; TUNIT: end:112; TUNIT-NEXT: [[RET:%.*]] = phi i32 [ [[RET0]], [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ]113; TUNIT-NEXT: ret i32 1114;115; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)116; CGSCC-LABEL: define {{[^@]+}}@test2_1117; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3:[0-9]+]] {118; CGSCC-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]119; CGSCC: if.true:120; CGSCC-NEXT: [[CALL:%.*]] = tail call i32 @return0() #[[ATTR12:[0-9]+]]121; CGSCC-NEXT: [[RET0:%.*]] = add i32 [[CALL]], 1122; CGSCC-NEXT: br label [[END:%.*]]123; CGSCC: if.false:124; CGSCC-NEXT: [[RET1:%.*]] = tail call i32 @return1() #[[ATTR12]]125; CGSCC-NEXT: br label [[END]]126; CGSCC: end:127; CGSCC-NEXT: [[RET:%.*]] = phi i32 [ [[RET0]], [[IF_TRUE]] ], [ [[RET1]], [[IF_FALSE]] ]128; CGSCC-NEXT: ret i32 1129;130 br i1 %c, label %if.true, label %if.false131if.true:132 %call = tail call i32 @return0()133 %ret0 = add i32 %call, 1134 br label %end135if.false:136 %ret1 = tail call i32 @return1()137 br label %end138end:139 140 %ret = phi i32 [ %ret0, %if.true ], [ %ret1, %if.false ]141 142 ret i32 1143}144 145 146 147define i32 @test2_2(i1 %c) {148; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)149; TUNIT-LABEL: define {{[^@]+}}@test2_2150; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {151; TUNIT-NEXT: ret i32 1152;153; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)154; CGSCC-LABEL: define {{[^@]+}}@test2_2155; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3]] {156; CGSCC-NEXT: [[RET:%.*]] = tail call noundef i32 @test2_1(i1 noundef [[C]]) #[[ATTR12]]157; CGSCC-NEXT: ret i32 [[RET]]158;159 %ret = tail call i32 @test2_1(i1 %c)160 ret i32 %ret161}162 163declare void @use(i32)164define void @test3(i1 %c) {165; TUNIT-LABEL: define {{[^@]+}}@test3166; TUNIT-SAME: (i1 noundef [[C:%.*]]) {167; TUNIT-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]168; TUNIT: if.true:169; TUNIT-NEXT: br label [[END:%.*]]170; TUNIT: if.false:171; TUNIT-NEXT: br label [[END]]172; TUNIT: end:173; TUNIT-NEXT: [[R:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ]174; TUNIT-NEXT: tail call void @use(i32 noundef 1)175; TUNIT-NEXT: ret void176;177; CGSCC-LABEL: define {{[^@]+}}@test3178; CGSCC-SAME: (i1 noundef [[C:%.*]]) {179; CGSCC-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]180; CGSCC: if.true:181; CGSCC-NEXT: br label [[END:%.*]]182; CGSCC: if.false:183; CGSCC-NEXT: [[RET1:%.*]] = tail call i32 @return1() #[[ATTR13:[0-9]+]]184; CGSCC-NEXT: br label [[END]]185; CGSCC: end:186; CGSCC-NEXT: [[R:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ [[RET1]], [[IF_FALSE]] ]187; CGSCC-NEXT: tail call void @use(i32 noundef [[R]])188; CGSCC-NEXT: ret void189;190 br i1 %c, label %if.true, label %if.false191if.true:192 br label %end193if.false:194 %ret1 = tail call i32 @return1()195 br label %end196end:197 198 %r = phi i32 [ 1, %if.true ], [ %ret1, %if.false ]199 200 tail call void @use(i32 %r)201 ret void202}203 204define void @test-select-phi(i1 %c) {205; CHECK-LABEL: define {{[^@]+}}@test-select-phi206; CHECK-SAME: (i1 [[C:%.*]]) {207; CHECK-NEXT: tail call void @use(i32 noundef 1)208; CHECK-NEXT: [[SELECT_NOT_SAME:%.*]] = select i1 [[C]], i32 1, i32 0209; CHECK-NEXT: tail call void @use(i32 noundef [[SELECT_NOT_SAME]])210; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]211; CHECK: if-true:212; CHECK-NEXT: br label [[END:%.*]]213; CHECK: if-false:214; CHECK-NEXT: br label [[END]]215; CHECK: end:216; CHECK-NEXT: [[PHI_SAME:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ]217; CHECK-NEXT: [[PHI_NOT_SAME:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ]218; CHECK-NEXT: [[PHI_SAME_PROP:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ]219; CHECK-NEXT: [[PHI_SAME_UNDEF:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ undef, [[IF_FALSE]] ]220; CHECK-NEXT: [[SELECT_NOT_SAME_UNDEF:%.*]] = select i1 [[C]], i32 [[PHI_NOT_SAME]], i32 undef221; CHECK-NEXT: tail call void @use(i32 noundef 1)222; CHECK-NEXT: tail call void @use(i32 noundef [[PHI_NOT_SAME]])223; CHECK-NEXT: tail call void @use(i32 noundef 1)224; CHECK-NEXT: tail call void @use(i32 1)225; CHECK-NEXT: tail call void @use(i32 [[SELECT_NOT_SAME_UNDEF]])226; CHECK-NEXT: ret void227;228 %select-same = select i1 %c, i32 1, i32 1229 tail call void @use(i32 %select-same)230 231 %select-not-same = select i1 %c, i32 1, i32 0232 tail call void @use(i32 %select-not-same)233 br i1 %c, label %if-true, label %if-false234if-true:235 br label %end236if-false:237 br label %end238end:239 %phi-same = phi i32 [ 1, %if-true ], [ 1, %if-false ]240 %phi-not-same = phi i32 [ 0, %if-true ], [ 1, %if-false ]241 %phi-same-prop = phi i32 [ 1, %if-true ], [ %select-same, %if-false ]242 %phi-same-undef = phi i32 [ 1, %if-true ], [ undef, %if-false ]243 %select-not-same-undef = select i1 %c, i32 %phi-not-same, i32 undef244 245 246 tail call void @use(i32 %phi-same)247 248 tail call void @use(i32 %phi-not-same)249 250 tail call void @use(i32 %phi-same-prop)251 252 tail call void @use(i32 %phi-same-undef)253 254 tail call void @use(i32 %select-not-same-undef)255 256 ret void257 258}259 260define i32 @ipccp1(i32 %a) {261; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)262; TUNIT-LABEL: define {{[^@]+}}@ipccp1263; TUNIT-SAME: (i32 returned [[A:%.*]]) #[[ATTR2]] {264; TUNIT-NEXT: br i1 true, label [[T:%.*]], label [[F:%.*]]265; TUNIT: t:266; TUNIT-NEXT: ret i32 [[A]]267; TUNIT: f:268; TUNIT-NEXT: unreachable269;270; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)271; CGSCC-LABEL: define {{[^@]+}}@ipccp1272; CGSCC-SAME: (i32 returned [[A:%.*]]) #[[ATTR1]] {273; CGSCC-NEXT: br i1 true, label [[T:%.*]], label [[F:%.*]]274; CGSCC: t:275; CGSCC-NEXT: ret i32 [[A]]276; CGSCC: f:277; CGSCC-NEXT: unreachable278;279 br i1 true, label %t, label %f280t:281 ret i32 %a282f:283 %r = call i32 @ipccp1(i32 5)284 ret i32 %r285}286 287define internal i1 @ipccp2i(i1 %a) {288; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)289; CGSCC-LABEL: define {{[^@]+}}@ipccp2i290; CGSCC-SAME: () #[[ATTR1]] {291; CGSCC-NEXT: br label [[T:%.*]]292; CGSCC: t:293; CGSCC-NEXT: ret i1 true294; CGSCC: f:295; CGSCC-NEXT: unreachable296;297 br i1 %a, label %t, label %f298t:299 ret i1 %a300f:301 %r = call i1 @ipccp2i(i1 false)302 ret i1 %r303}304 305define i1 @ipccp2() {306; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)307; TUNIT-LABEL: define {{[^@]+}}@ipccp2308; TUNIT-SAME: () #[[ATTR2]] {309; TUNIT-NEXT: ret i1 true310;311; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)312; CGSCC-LABEL: define {{[^@]+}}@ipccp2313; CGSCC-SAME: () #[[ATTR3]] {314; CGSCC-NEXT: [[R:%.*]] = call noundef i1 @ipccp2i() #[[ATTR12]]315; CGSCC-NEXT: ret i1 [[R]]316;317 %r = call i1 @ipccp2i(i1 true)318 ret i1 %r319}320 321define internal i1 @ipccp2ib(i1 %a) {322; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)323; CGSCC-LABEL: define {{[^@]+}}@ipccp2ib324; CGSCC-SAME: () #[[ATTR1]] {325; CGSCC-NEXT: br label [[T:%.*]]326; CGSCC: t:327; CGSCC-NEXT: ret i1 true328; CGSCC: f:329; CGSCC-NEXT: unreachable330;331 br i1 %a, label %t, label %f332t:333 ret i1 true334f:335 %r = call i1 @ipccp2ib(i1 false)336 ret i1 %r337}338 339define i1 @ipccp2b() {340; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)341; TUNIT-LABEL: define {{[^@]+}}@ipccp2b342; TUNIT-SAME: () #[[ATTR2]] {343; TUNIT-NEXT: ret i1 true344;345; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)346; CGSCC-LABEL: define {{[^@]+}}@ipccp2b347; CGSCC-SAME: () #[[ATTR3]] {348; CGSCC-NEXT: [[R:%.*]] = call noundef i1 @ipccp2ib() #[[ATTR12]]349; CGSCC-NEXT: ret i1 [[R]]350;351 %r = call i1 @ipccp2ib(i1 true)352 ret i1 %r353}354 355define internal i32 @ipccp3i(i32 %a) {356; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)357; CGSCC-LABEL: define {{[^@]+}}@ipccp3i358; CGSCC-SAME: () #[[ATTR1]] {359; CGSCC-NEXT: br label [[T:%.*]]360; CGSCC: t:361; CGSCC-NEXT: ret i32 7362; CGSCC: f:363; CGSCC-NEXT: unreachable364;365 %c = icmp eq i32 %a, 7366 br i1 %c, label %t, label %f367t:368 ret i32 %a369f:370 %r = call i32 @ipccp3i(i32 5)371 ret i32 %r372}373 374define i32 @ipccp3() {375; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)376; TUNIT-LABEL: define {{[^@]+}}@ipccp3377; TUNIT-SAME: () #[[ATTR2]] {378; TUNIT-NEXT: ret i32 7379;380; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)381; CGSCC-LABEL: define {{[^@]+}}@ipccp3382; CGSCC-SAME: () #[[ATTR3]] {383; CGSCC-NEXT: [[R:%.*]] = call noundef i32 @ipccp3i() #[[ATTR12]]384; CGSCC-NEXT: ret i32 [[R]]385;386 %r = call i32 @ipccp3i(i32 7)387 ret i32 %r388}389 390define internal i32 @ipccp4ia(i1 %c) {391; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)392; CGSCC-LABEL: define {{[^@]+}}@ipccp4ia393; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR1]] {394; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]395; CGSCC: t:396; CGSCC-NEXT: ret i32 0397; CGSCC: f:398; CGSCC-NEXT: ret i32 1399;400 br i1 %c, label %t, label %f401t:402 ret i32 0403f:404 ret i32 1405}406define internal i32 @ipccp4ib(i32 %a) {407; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)408; CGSCC-LABEL: define {{[^@]+}}@ipccp4ib409; CGSCC-SAME: () #[[ATTR3]] {410; CGSCC-NEXT: br label [[T:%.*]]411; CGSCC: t:412; CGSCC-NEXT: [[R:%.*]] = call noundef i32 @ipccp4ia(i1 noundef true) #[[ATTR12]]413; CGSCC-NEXT: ret i32 [[R]]414; CGSCC: f:415; CGSCC-NEXT: unreachable416;417 %c = icmp eq i32 %a, 7418 br i1 %c, label %t, label %f419t:420 %r = call i32 @ipccp4ia(i1 %c)421 ret i32 %r422f:423 ret i32 1424}425 426define i32 @ipccp4(i1 %c) {427; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)428; TUNIT-LABEL: define {{[^@]+}}@ipccp4429; TUNIT-SAME: (i1 noundef [[C:%.*]]) #[[ATTR2]] {430; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]431; TUNIT: t:432; TUNIT-NEXT: br label [[F]]433; TUNIT: f:434; TUNIT-NEXT: ret i32 0435;436; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)437; CGSCC-LABEL: define {{[^@]+}}@ipccp4438; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3]] {439; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]440; CGSCC: t:441; CGSCC-NEXT: br label [[F]]442; CGSCC: f:443; CGSCC-NEXT: [[R:%.*]] = call noundef i32 @ipccp4ib() #[[ATTR12]]444; CGSCC-NEXT: ret i32 [[R]]445;446 br i1 %c, label %t, label %f447t:448 %q = call i32 @ipccp4ia(i1 undef)449 br label %f450f:451 %r = call i32 @ipccp4ib(i32 7)452 ret i32 %r453}454 455; Do not touch complicated arguments (for now)456%struct.X = type { ptr }457define internal ptr @test_inalloca(ptr inalloca(i32) %a) {458; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)459; TUNIT-LABEL: define {{[^@]+}}@test_inalloca460; TUNIT-SAME: (ptr noalias nofree nonnull returned writeonly inalloca(i32) dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] {461; TUNIT-NEXT: ret ptr [[A]]462;463; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)464; CGSCC-LABEL: define {{[^@]+}}@test_inalloca465; CGSCC-SAME: (ptr noalias nofree noundef nonnull returned writeonly inalloca(i32) dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {466; CGSCC-NEXT: ret ptr [[A]]467;468 ret ptr %a469}470define ptr @complicated_args_inalloca(ptr %arg) {471; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)472; TUNIT-LABEL: define {{[^@]+}}@complicated_args_inalloca473; TUNIT-SAME: (ptr nofree nonnull readnone "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR2]] {474; TUNIT-NEXT: [[CALL:%.*]] = call nonnull dereferenceable(4) ptr @test_inalloca(ptr noalias nofree nonnull writeonly inalloca(i32) "no-capture-maybe-returned" [[ARG]]) #[[ATTR9:[0-9]+]]475; TUNIT-NEXT: ret ptr [[CALL]]476;477; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)478; CGSCC-LABEL: define {{[^@]+}}@complicated_args_inalloca479; CGSCC-SAME: (ptr nofree noundef nonnull readnone dereferenceable(4) [[ARG:%.*]]) #[[ATTR3]] {480; CGSCC-NEXT: [[CALL:%.*]] = call noalias noundef nonnull dereferenceable(4) ptr @test_inalloca(ptr noalias nofree noundef nonnull writeonly inalloca(i32) dereferenceable(4) [[ARG]]) #[[ATTR12]]481; CGSCC-NEXT: ret ptr [[CALL]]482;483 %call = call ptr @test_inalloca(ptr inalloca(i32) %arg)484 ret ptr %call485}486 487define internal ptr @test_preallocated(ptr preallocated(i32) %a) {488; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)489; TUNIT-LABEL: define {{[^@]+}}@test_preallocated490; TUNIT-SAME: (ptr noalias nofree noundef nonnull returned writeonly preallocated(i32) align 4294967296 dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] {491; TUNIT-NEXT: ret ptr [[A]]492;493; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)494; CGSCC-LABEL: define {{[^@]+}}@test_preallocated495; CGSCC-SAME: (ptr noalias nofree noundef nonnull returned writeonly preallocated(i32) align 4294967296 dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {496; CGSCC-NEXT: ret ptr [[A]]497;498 ret ptr %a499}500define ptr @complicated_args_preallocated() {501; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn502; TUNIT-LABEL: define {{[^@]+}}@complicated_args_preallocated503; TUNIT-SAME: () #[[ATTR3:[0-9]+]] {504; TUNIT-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR10:[0-9]+]]505; TUNIT-NEXT: [[CALL:%.*]] = call noundef nonnull align 4294967296 dereferenceable(4) ptr @test_preallocated(ptr nofree noundef writeonly preallocated(i32) null) #[[ATTR9]] [ "preallocated"(token [[C]]) ]506; TUNIT-NEXT: ret ptr [[CALL]]507;508; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn509; CGSCC-LABEL: define {{[^@]+}}@complicated_args_preallocated510; CGSCC-SAME: () #[[ATTR4:[0-9]+]] {511; CGSCC-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR13]]512; CGSCC-NEXT: [[CALL:%.*]] = call ptr @test_preallocated(ptr nofree noundef writeonly preallocated(i32) null) #[[ATTR14:[0-9]+]] [ "preallocated"(token [[C]]) ]513; CGSCC-NEXT: unreachable514;515 %c = call token @llvm.call.preallocated.setup(i32 1)516 %call = call ptr @test_preallocated(ptr preallocated(i32) null) ["preallocated"(token %c)]517 ret ptr %call518}519 520define internal void @test_sret(ptr sret(%struct.X) %a, ptr %b) {521;522; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)523; TUNIT-LABEL: define {{[^@]+}}@test_sret524; TUNIT-SAME: (ptr noalias nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 4294967296 dereferenceable_or_null(8) [[A:%.*]], ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[B:%.*]]) #[[ATTR4:[0-9]+]] {525; TUNIT-NEXT: store ptr [[A]], ptr [[B]], align 8526; TUNIT-NEXT: ret void527;528; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)529; CGSCC-LABEL: define {{[^@]+}}@test_sret530; CGSCC-SAME: (ptr noalias nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 4294967296 dereferenceable_or_null(8) [[A:%.*]], ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[B:%.*]]) #[[ATTR5:[0-9]+]] {531; CGSCC-NEXT: store ptr [[A]], ptr [[B]], align 8532; CGSCC-NEXT: ret void533;534 store ptr %a, ptr %b535 ret void536}537; FIXME: Alignment and dereferenceability are not propagated to the argument538define void @complicated_args_sret(ptr %b) {539;540;541; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)542; TUNIT-LABEL: define {{[^@]+}}@complicated_args_sret543; TUNIT-SAME: (ptr nofree writeonly captures(none) [[B:%.*]]) #[[ATTR4]] {544; TUNIT-NEXT: call void @test_sret(ptr nofree noundef writeonly sret([[STRUCT_X:%.*]]) null, ptr nofree noundef writeonly align 8 captures(none) [[B]]) #[[ATTR11:[0-9]+]]545; TUNIT-NEXT: ret void546;547; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: write)548; CGSCC-LABEL: define {{[^@]+}}@complicated_args_sret549; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[B:%.*]]) #[[ATTR6:[0-9]+]] {550; CGSCC-NEXT: call void @test_sret(ptr nofree noundef writeonly sret([[STRUCT_X:%.*]]) dereferenceable_or_null(8) null, ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[B]]) #[[ATTR15:[0-9]+]]551; CGSCC-NEXT: ret void552;553 call void @test_sret(ptr sret(%struct.X) null, ptr %b)554 ret void555}556 557define internal ptr @test_nest(ptr nest %a) {558; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)559; CGSCC-LABEL: define {{[^@]+}}@test_nest560; CGSCC-SAME: (ptr nest noalias nofree readnone align 4294967296 captures(none) [[A:%.*]]) #[[ATTR1]] {561; CGSCC-NEXT: ret ptr null562;563 ret ptr %a564}565define ptr @complicated_args_nest() {566; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)567; TUNIT-LABEL: define {{[^@]+}}@complicated_args_nest568; TUNIT-SAME: () #[[ATTR2]] {569; TUNIT-NEXT: ret ptr null570;571; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)572; CGSCC-LABEL: define {{[^@]+}}@complicated_args_nest573; CGSCC-SAME: () #[[ATTR3]] {574; CGSCC-NEXT: [[CALL:%.*]] = call noalias noundef align 4294967296 ptr @test_nest(ptr nofree noundef readnone null) #[[ATTR12]]575; CGSCC-NEXT: ret ptr [[CALL]]576;577 %call = call ptr @test_nest(ptr null)578 ret ptr %call579}580 581@S = external global %struct.X582define internal void @test_byval(ptr byval(%struct.X) %a) {583; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)584; TUNIT-LABEL: define {{[^@]+}}@test_byval585; TUNIT-SAME: (ptr [[TMP0:%.*]]) #[[ATTR4]] {586; TUNIT-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8587; TUNIT-NEXT: store ptr [[TMP0]], ptr [[A_PRIV]], align 8588; TUNIT-NEXT: store ptr null, ptr [[A_PRIV]], align 8589; TUNIT-NEXT: ret void590;591; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)592; CGSCC-LABEL: define {{[^@]+}}@test_byval593; CGSCC-SAME: (ptr nofree [[TMP0:%.*]]) #[[ATTR5]] {594; CGSCC-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8595; CGSCC-NEXT: store ptr [[TMP0]], ptr [[A_PRIV]], align 8596; CGSCC-NEXT: store ptr null, ptr [[A_PRIV]], align 8597; CGSCC-NEXT: ret void598;599 store ptr null, ptr %a600 ret void601}602define void @complicated_args_byval() {603; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)604; TUNIT-LABEL: define {{[^@]+}}@complicated_args_byval605; TUNIT-SAME: () #[[ATTR5:[0-9]+]] {606; TUNIT-NEXT: [[TMP1:%.*]] = load ptr, ptr @S, align 8607; TUNIT-NEXT: call void @test_byval(ptr [[TMP1]]) #[[ATTR11]]608; TUNIT-NEXT: ret void609;610; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn611; CGSCC-LABEL: define {{[^@]+}}@complicated_args_byval612; CGSCC-SAME: () #[[ATTR4]] {613; CGSCC-NEXT: [[TMP1:%.*]] = load ptr, ptr @S, align 8614; CGSCC-NEXT: call void @test_byval(ptr nofree writeonly [[TMP1]]) #[[ATTR15]]615; CGSCC-NEXT: ret void616;617 call void @test_byval(ptr byval(%struct.X) @S)618 ret void619}620 621declare void @sync()622; Make sure we *do not* load @S here!623define internal ptr @test_byval2(ptr byval(%struct.X) %a) {624; CHECK-LABEL: define {{[^@]+}}@test_byval2625; CHECK-SAME: (ptr [[TMP0:%.*]]) {626; CHECK-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8627; CHECK-NEXT: store ptr [[TMP0]], ptr [[A_PRIV]], align 8628; CHECK-NEXT: call void @sync()629; CHECK-NEXT: [[L:%.*]] = load ptr, ptr [[A_PRIV]], align 8630; CHECK-NEXT: ret ptr [[L]]631;632 call void @sync()633 %l = load ptr, ptr %a634 ret ptr %l635}636define ptr @complicated_args_byval2() {637;638; CHECK-LABEL: define {{[^@]+}}@complicated_args_byval2() {639; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr @S, align 8640; CHECK-NEXT: [[C:%.*]] = call ptr @test_byval2(ptr [[TMP1]])641; CHECK-NEXT: ret ptr [[C]]642;643 %c = call ptr @test_byval2(ptr byval(%struct.X) @S)644 ret ptr %c645}646 647define void @fixpoint_changed(ptr %p) {648; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)649; TUNIT-LABEL: define {{[^@]+}}@fixpoint_changed650; TUNIT-SAME: (ptr nofree writeonly captures(none) [[P:%.*]]) #[[ATTR4]] {651; TUNIT-NEXT: entry:652; TUNIT-NEXT: br label [[FOR_COND:%.*]]653; TUNIT: for.cond:654; TUNIT-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[SW_EPILOG:%.*]] ]655; TUNIT-NEXT: [[CMP:%.*]] = icmp slt i32 [[J_0]], 30656; TUNIT-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]657; TUNIT: for.body:658; TUNIT-NEXT: switch i32 [[J_0]], label [[SW_EPILOG]] [659; TUNIT-NEXT: i32 1, label [[SW_BB:%.*]]660; TUNIT-NEXT: ]661; TUNIT: sw.bb:662; TUNIT-NEXT: br label [[SW_EPILOG]]663; TUNIT: sw.epilog:664; TUNIT-NEXT: [[X_0:%.*]] = phi i32 [ 255, [[FOR_BODY]] ], [ 253, [[SW_BB]] ]665; TUNIT-NEXT: store i32 [[X_0]], ptr [[P]], align 4666; TUNIT-NEXT: [[INC]] = add nsw i32 [[J_0]], 1667; TUNIT-NEXT: br label [[FOR_COND]]668; TUNIT: for.end:669; TUNIT-NEXT: ret void670;671; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)672; CGSCC-LABEL: define {{[^@]+}}@fixpoint_changed673; CGSCC-SAME: (ptr nofree writeonly captures(none) [[P:%.*]]) #[[ATTR5]] {674; CGSCC-NEXT: entry:675; CGSCC-NEXT: br label [[FOR_COND:%.*]]676; CGSCC: for.cond:677; CGSCC-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[SW_EPILOG:%.*]] ]678; CGSCC-NEXT: [[CMP:%.*]] = icmp slt i32 [[J_0]], 30679; CGSCC-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]680; CGSCC: for.body:681; CGSCC-NEXT: switch i32 [[J_0]], label [[SW_EPILOG]] [682; CGSCC-NEXT: i32 1, label [[SW_BB:%.*]]683; CGSCC-NEXT: ]684; CGSCC: sw.bb:685; CGSCC-NEXT: br label [[SW_EPILOG]]686; CGSCC: sw.epilog:687; CGSCC-NEXT: [[X_0:%.*]] = phi i32 [ 255, [[FOR_BODY]] ], [ 253, [[SW_BB]] ]688; CGSCC-NEXT: store i32 [[X_0]], ptr [[P]], align 4689; CGSCC-NEXT: [[INC]] = add nsw i32 [[J_0]], 1690; CGSCC-NEXT: br label [[FOR_COND]]691; CGSCC: for.end:692; CGSCC-NEXT: ret void693;694entry:695 br label %for.cond696 697for.cond:698 %j.0 = phi i32 [ 0, %entry ], [ %inc, %sw.epilog ]699 %cmp = icmp slt i32 %j.0, 30700 br i1 %cmp, label %for.body, label %for.end701 702for.body:703 switch i32 %j.0, label %sw.epilog [704 i32 1, label %sw.bb705 ]706 707sw.bb:708 br label %sw.epilog709 710sw.epilog:711 %x.0 = phi i32 [ 255, %for.body ], [ 253, %sw.bb ]712 store i32 %x.0, ptr %p713 %inc = add nsw i32 %j.0, 1714 br label %for.cond715 716for.end:717 ret void718}719 720; Check we merge undef and a constant properly.721define i8 @caller0() {722; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)723; TUNIT-LABEL: define {{[^@]+}}@caller0724; TUNIT-SAME: () #[[ATTR2]] {725; TUNIT-NEXT: ret i8 49726;727; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)728; CGSCC-LABEL: define {{[^@]+}}@caller0729; CGSCC-SAME: () #[[ATTR3]] {730; CGSCC-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]]731; CGSCC-NEXT: ret i8 [[C]]732;733 %c = call i8 @callee(i8 undef)734 ret i8 %c735}736define i8 @caller1() {737; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)738; TUNIT-LABEL: define {{[^@]+}}@caller1739; TUNIT-SAME: () #[[ATTR2]] {740; TUNIT-NEXT: ret i8 49741;742; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)743; CGSCC-LABEL: define {{[^@]+}}@caller1744; CGSCC-SAME: () #[[ATTR3]] {745; CGSCC-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]]746; CGSCC-NEXT: ret i8 [[C]]747;748 %c = call i8 @callee(i8 undef)749 ret i8 %c750}751define i8 @caller2() {752; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)753; TUNIT-LABEL: define {{[^@]+}}@caller2754; TUNIT-SAME: () #[[ATTR2]] {755; TUNIT-NEXT: ret i8 49756;757; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)758; CGSCC-LABEL: define {{[^@]+}}@caller2759; CGSCC-SAME: () #[[ATTR3]] {760; CGSCC-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]]761; CGSCC-NEXT: ret i8 [[C]]762;763 %c = call i8 @callee(i8 undef)764 ret i8 %c765}766define i8 @caller_middle() {767; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)768; TUNIT-LABEL: define {{[^@]+}}@caller_middle769; TUNIT-SAME: () #[[ATTR2]] {770; TUNIT-NEXT: ret i8 49771;772; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)773; CGSCC-LABEL: define {{[^@]+}}@caller_middle774; CGSCC-SAME: () #[[ATTR3]] {775; CGSCC-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]]776; CGSCC-NEXT: ret i8 [[C]]777;778 %c = call i8 @callee(i8 42)779 ret i8 %c780}781define i8 @caller3() {782; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)783; TUNIT-LABEL: define {{[^@]+}}@caller3784; TUNIT-SAME: () #[[ATTR2]] {785; TUNIT-NEXT: ret i8 49786;787; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)788; CGSCC-LABEL: define {{[^@]+}}@caller3789; CGSCC-SAME: () #[[ATTR3]] {790; CGSCC-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]]791; CGSCC-NEXT: ret i8 [[C]]792;793 %c = call i8 @callee(i8 undef)794 ret i8 %c795}796define i8 @caller4() {797; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)798; TUNIT-LABEL: define {{[^@]+}}@caller4799; TUNIT-SAME: () #[[ATTR2]] {800; TUNIT-NEXT: ret i8 49801;802; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)803; CGSCC-LABEL: define {{[^@]+}}@caller4804; CGSCC-SAME: () #[[ATTR3]] {805; CGSCC-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]]806; CGSCC-NEXT: ret i8 [[C]]807;808 %c = call i8 @callee(i8 undef)809 ret i8 %c810}811define internal i8 @callee(i8 %a) {812; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)813; CGSCC-LABEL: define {{[^@]+}}@callee814; CGSCC-SAME: () #[[ATTR1]] {815; CGSCC-NEXT: ret i8 49816;817 %c = add i8 %a, 7818 ret i8 %c819}820 821define void @user_as3() {822; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)823; TUNIT-LABEL: define {{[^@]+}}@user_as3824; TUNIT-SAME: () #[[ATTR5]] {825; TUNIT-NEXT: store i32 0, ptr addrspace(3) @ConstAS3Ptr, align 4826; TUNIT-NEXT: ret void827;828; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(write)829; CGSCC-LABEL: define {{[^@]+}}@user_as3830; CGSCC-SAME: () #[[ATTR7:[0-9]+]] {831; CGSCC-NEXT: [[CALL:%.*]] = call fastcc align 4 ptr addrspace(3) @const_ptr_return_as3() #[[ATTR12]]832; CGSCC-NEXT: store i32 0, ptr addrspace(3) [[CALL]], align 4833; CGSCC-NEXT: ret void834;835 %call = call fastcc ptr addrspace(3) @const_ptr_return_as3()836 store i32 0, ptr addrspace(3) %call837 ret void838}839define void @user() {840; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)841; TUNIT-LABEL: define {{[^@]+}}@user842; TUNIT-SAME: () #[[ATTR5]] {843; TUNIT-NEXT: store i32 0, ptr addrspacecast (ptr addrspace(3) @ConstAS3Ptr to ptr), align 4844; TUNIT-NEXT: ret void845;846; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(write)847; CGSCC-LABEL: define {{[^@]+}}@user848; CGSCC-SAME: () #[[ATTR7]] {849; CGSCC-NEXT: [[CALL:%.*]] = call fastcc align 4 ptr @const_ptr_return() #[[ATTR12]]850; CGSCC-NEXT: store i32 0, ptr [[CALL]], align 4851; CGSCC-NEXT: ret void852;853 %call = call fastcc ptr @const_ptr_return()854 store i32 0, ptr %call855 ret void856}857 858 859define i1 @test_merge_with_undef_values_ptr(i1 %c) {860; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)861; TUNIT-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr862; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {863; TUNIT-NEXT: ret i1 false864;865; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)866; CGSCC-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr867; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] {868; CGSCC-NEXT: [[R1:%.*]] = call i1 @undef_then_null(i1 [[C]]) #[[ATTR12]]869; CGSCC-NEXT: ret i1 [[R1]]870;871 %r1 = call i1 @undef_then_null(i1 %c, ptr undef, ptr undef)872 ret i1 %r1873}874define internal i1 @undef_then_null(i1 %c, ptr %i32Aptr, ptr %i32Bptr) {875; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)876; CGSCC-LABEL: define {{[^@]+}}@undef_then_null877; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] {878; CGSCC-NEXT: [[OR:%.*]] = or i1 false, [[C]]879; CGSCC-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]]880; CGSCC: a:881; CGSCC-NEXT: ret i1 false882; CGSCC: b:883; CGSCC-NEXT: ret i1 false884;885 %cmp1 = icmp eq ptr %i32Aptr, %i32Bptr886 %cmp2 = icmp eq i1 %cmp1, false887 %or = or i1 %cmp2, %c888 br i1 %or, label %a, label %b889a:890 %r2 = call i1 @undef_then_null(i1 false, ptr null, ptr null)891 ret i1 %r2892b:893 ret i1 %cmp2894}895 896define i1 @test_merge_with_undef_values(i1 %c) {897; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)898; TUNIT-LABEL: define {{[^@]+}}@test_merge_with_undef_values899; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {900; TUNIT-NEXT: ret i1 false901;902; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)903; CGSCC-LABEL: define {{[^@]+}}@test_merge_with_undef_values904; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] {905; CGSCC-NEXT: [[R1:%.*]] = call i1 @undef_then_1(i1 [[C]]) #[[ATTR12]]906; CGSCC-NEXT: ret i1 [[R1]]907;908 %r1 = call i1 @undef_then_1(i1 %c, i32 undef, i32 undef)909 ret i1 %r1910}911define internal i1 @undef_then_1(i1 %c, i32 %i32A, i32 %i32B) {912;913; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)914; CGSCC-LABEL: define {{[^@]+}}@undef_then_1915; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] {916; CGSCC-NEXT: [[OR:%.*]] = or i1 false, [[C]]917; CGSCC-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]]918; CGSCC: a:919; CGSCC-NEXT: ret i1 false920; CGSCC: b:921; CGSCC-NEXT: ret i1 false922;923 %cmp1 = icmp eq i32 %i32A, %i32B924 %cmp2 = icmp eq i1 %cmp1, false925 %or = or i1 %cmp2, %c926 br i1 %or, label %a, label %b927a:928 %r2 = call i1 @undef_then_1(i1 false, i32 1, i32 1)929 ret i1 %r2930b:931 ret i1 %cmp2932}933 934define i32 @test_select(i32 %c) {935; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)936; TUNIT-LABEL: define {{[^@]+}}@test_select937; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR2]] {938; TUNIT-NEXT: ret i32 42939;940; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)941; CGSCC-LABEL: define {{[^@]+}}@test_select942; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR3]] {943; CGSCC-NEXT: [[CALL:%.*]] = call noundef i32 @select() #[[ATTR12]]944; CGSCC-NEXT: ret i32 [[CALL]]945;946 %call = call i32 @select(i1 1, i32 42, i32 %c)947 ret i32 %call948}949 950define internal i32 @select(i1 %a, i32 %b, i32 %c) {951; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)952; CGSCC-LABEL: define {{[^@]+}}@select953; CGSCC-SAME: () #[[ATTR1]] {954; CGSCC-NEXT: ret i32 42955;956 %s = select i1 %a, i32 %b, i32 %c957 ret i32 %s958}959 960define i1 @icmp() {961; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)962; TUNIT-LABEL: define {{[^@]+}}@icmp963; TUNIT-SAME: () #[[ATTR2]] {964; TUNIT-NEXT: ret i1 true965;966; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)967; CGSCC-LABEL: define {{[^@]+}}@icmp968; CGSCC-SAME: () #[[ATTR1]] {969; CGSCC-NEXT: ret i1 true970;971 %c = icmp eq ptr null, null972 ret i1 %c973}974 975define void @test_callee_is_undef(ptr %fn) {976; TUNIT-LABEL: define {{[^@]+}}@test_callee_is_undef977; TUNIT-SAME: (ptr nofree captures(none) [[FN:%.*]]) {978; TUNIT-NEXT: call void @unknown_calle_arg_is_undef(ptr nofree noundef captures(none) [[FN]])979; TUNIT-NEXT: ret void980;981; CGSCC-LABEL: define {{[^@]+}}@test_callee_is_undef982; CGSCC-SAME: (ptr nofree noundef nonnull captures(none) [[FN:%.*]]) {983; CGSCC-NEXT: call void @unknown_calle_arg_is_undef(ptr nofree noundef nonnull captures(none) [[FN]])984; CGSCC-NEXT: ret void985;986 call void @callee_is_undef(ptr undef)987 call void @unknown_calle_arg_is_undef(ptr %fn, i32 undef)988 ret void989}990define internal void @callee_is_undef(ptr %fn) {991;992; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)993; CGSCC-LABEL: define {{[^@]+}}@callee_is_undef994; CGSCC-SAME: () #[[ATTR1]] {995; CGSCC-NEXT: unreachable996;997 call void %fn()998 ret void999}1000define internal void @unknown_calle_arg_is_undef(ptr %fn, i32 %arg) {1001;1002; CHECK-LABEL: define {{[^@]+}}@unknown_calle_arg_is_undef1003; CHECK-SAME: (ptr nofree noundef nonnull captures(none) [[FN:%.*]]) {1004; CHECK-NEXT: call void [[FN]](i32 undef)1005; CHECK-NEXT: ret void1006;1007 call void %fn(i32 %arg)1008 ret void1009}1010 1011; Taken from 506831012; {{{1013 1014@g = internal constant { [2 x ptr] } { [2 x ptr] [ptr @f1, ptr @f2] }1015 1016define internal void @f1(ptr %a) {1017; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)1018; TUNIT-LABEL: define {{[^@]+}}@f11019; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[A:%.*]]) #[[ATTR4]] {1020; TUNIT-NEXT: entry:1021; TUNIT-NEXT: store ptr @g, ptr [[A]], align 81022; TUNIT-NEXT: ret void1023;1024; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)1025; CGSCC-LABEL: define {{[^@]+}}@f11026; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[A:%.*]]) #[[ATTR5]] {1027; CGSCC-NEXT: entry:1028; CGSCC-NEXT: store ptr @g, ptr [[A]], align 81029; CGSCC-NEXT: ret void1030;1031entry:1032 store ptr @g , ptr %a, align 81033 ret void1034}1035 1036define internal void @f2(ptr %a) {1037; CHECK-LABEL: define {{[^@]+}}@f21038; CHECK-SAME: (ptr [[A:%.*]]) {1039; CHECK-NEXT: cont461:1040; CHECK-NEXT: call void @f3(ptr [[A]], ptr nofree captures(none) [[A]])1041; CHECK-NEXT: ret void1042;1043cont461:1044 call void @f3(ptr %a, ptr %a)1045 ret void1046}1047 1048define internal void @f3(ptr %a1, ptr %a) {1049; CHECK-LABEL: define {{[^@]+}}@f31050; CHECK-SAME: (ptr [[A1:%.*]], ptr nofree captures(none) [[A:%.*]]) {1051; CHECK-NEXT: entry:1052; CHECK-NEXT: [[CALL20:%.*]] = call i1 @f9()1053; CHECK-NEXT: br i1 [[CALL20]], label [[LAND_LHS_TRUE:%.*]], label [[IF_END40:%.*]]1054; CHECK: land.lhs.true:1055; CHECK-NEXT: [[TMP0:%.*]] = call i1 [[A]](ptr [[A1]])1056; CHECK-NEXT: br label [[IF_END40]]1057; CHECK: if.end40:1058; CHECK-NEXT: ret void1059;1060entry:1061 %call20 = call i1 @f9()1062 br i1 %call20, label %land.lhs.true, label %if.end401063 1064land.lhs.true:1065 call i1 %a(ptr %a1)1066 br label %if.end401067 1068if.end40:1069 ret void1070}1071 1072define linkonce_odr i1 @f9() {1073; CHECK-LABEL: define {{[^@]+}}@f9() {1074; CHECK-NEXT: entry:1075; CHECK-NEXT: ret i1 false1076;1077entry:1078 ret i1 false1079}1080 1081; }}}1082 1083 1084define i1 @test_cmp_null_after_cast() {1085; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1086; TUNIT-LABEL: define {{[^@]+}}@test_cmp_null_after_cast1087; TUNIT-SAME: () #[[ATTR2]] {1088; TUNIT-NEXT: ret i1 true1089;1090; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)1091; CGSCC-LABEL: define {{[^@]+}}@test_cmp_null_after_cast1092; CGSCC-SAME: () #[[ATTR3]] {1093; CGSCC-NEXT: [[C:%.*]] = call noundef i1 @cmp_null_after_cast() #[[ATTR12]]1094; CGSCC-NEXT: ret i1 [[C]]1095;1096 %c = call i1 @cmp_null_after_cast(i32 0, i8 0)1097 ret i1 %c1098}1099define internal i1 @cmp_null_after_cast(i32 %a, i8 %b) {1100; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1101; CGSCC-LABEL: define {{[^@]+}}@cmp_null_after_cast1102; CGSCC-SAME: () #[[ATTR1]] {1103; CGSCC-NEXT: ret i1 true1104;1105 %t = trunc i32 %a to i81106 %c = icmp eq i8 %t, %b1107 ret i1 %c1108}1109 1110 1111declare ptr @m()1112 1113define i32 @test(i1 %c) {1114; TUNIT-LABEL: define {{[^@]+}}@test1115; TUNIT-SAME: (i1 [[C:%.*]]) {1116; TUNIT-NEXT: [[R1:%.*]] = call i32 @ctx_test1(i1 noundef [[C]])1117; TUNIT-NEXT: [[R2:%.*]] = call range(i32 0, -2147483648) i32 @ctx_test2(i1 noundef [[C]])1118; TUNIT-NEXT: [[ADD:%.*]] = add i32 [[R1]], [[R2]]1119; TUNIT-NEXT: ret i32 [[ADD]]1120;1121; CGSCC-LABEL: define {{[^@]+}}@test1122; CGSCC-SAME: (i1 noundef [[C:%.*]]) {1123; CGSCC-NEXT: [[R1:%.*]] = call i32 @ctx_test1(i1 noundef [[C]])1124; CGSCC-NEXT: [[R2:%.*]] = call i32 @ctx_test2(i1 noundef [[C]])1125; CGSCC-NEXT: [[ADD:%.*]] = add i32 [[R1]], [[R2]]1126; CGSCC-NEXT: ret i32 [[ADD]]1127;1128 %r1 = call i32 @ctx_test1(i1 %c)1129 %r2 = call i32 @ctx_test2(i1 %c)1130 %add = add i32 %r1, %r21131 ret i32 %add1132}1133 1134define internal i32 @ctx_test1(i1 %c) {1135; CHECK-LABEL: define {{[^@]+}}@ctx_test11136; CHECK-SAME: (i1 noundef [[C:%.*]]) {1137; CHECK-NEXT: entry:1138; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[JOIN:%.*]]1139; CHECK: then:1140; CHECK-NEXT: [[M:%.*]] = tail call ptr @m()1141; CHECK-NEXT: [[I:%.*]] = ptrtoint ptr [[M]] to i641142; CHECK-NEXT: br label [[JOIN]]1143; CHECK: join:1144; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ [[I]], [[THEN]] ], [ undef, [[ENTRY:%.*]] ]1145; CHECK-NEXT: [[RET:%.*]] = trunc i64 [[PHI]] to i321146; CHECK-NEXT: ret i32 [[RET]]1147;1148entry:1149 br i1 %c, label %then, label %join1150 1151then:1152 %m = tail call ptr @m()1153 %i = ptrtoint ptr %m to i641154 br label %join1155 1156join:1157 %phi = phi i64 [ %i, %then ], [ undef, %entry ]1158 %ret = trunc i64 %phi to i321159 ret i32 %ret1160}1161 1162define internal i32 @ctx_test2(i1 %c) {1163; CHECK-LABEL: define {{[^@]+}}@ctx_test21164; CHECK-SAME: (i1 noundef [[C:%.*]]) {1165; CHECK-NEXT: entry:1166; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[JOIN:%.*]]1167; CHECK: then:1168; CHECK-NEXT: [[M:%.*]] = tail call ptr @m()1169; CHECK-NEXT: [[I:%.*]] = ptrtoint ptr [[M]] to i321170; CHECK-NEXT: br label [[JOIN]]1171; CHECK: join:1172; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[I]], [[THEN]] ], [ undef, [[ENTRY:%.*]] ]1173; CHECK-NEXT: [[RET:%.*]] = lshr i32 [[PHI]], 11174; CHECK-NEXT: ret i32 [[RET]]1175;1176entry:1177 br i1 %c, label %then, label %join1178 1179then:1180 %m = tail call ptr @m()1181 %i = ptrtoint ptr %m to i321182 br label %join1183 1184join:1185 %phi = phi i32 [ %i, %then ], [ undef, %entry ]1186 %ret = lshr i32 %phi, 11187 ret i32 %ret1188 1189 uselistorder label %join, { 1, 0 }1190}1191 1192define i1 @test_liveness(i1 %c) {1193; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1194; TUNIT-LABEL: define {{[^@]+}}@test_liveness1195; TUNIT-SAME: (i1 noundef [[C:%.*]]) #[[ATTR2]] {1196; TUNIT-NEXT: entry:1197; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]1198; TUNIT: t:1199; TUNIT-NEXT: br label [[F]]1200; TUNIT: f:1201; TUNIT-NEXT: ret i1 false1202;1203; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)1204; CGSCC-LABEL: define {{[^@]+}}@test_liveness1205; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3]] {1206; CGSCC-NEXT: entry:1207; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]1208; CGSCC: t:1209; CGSCC-NEXT: br label [[F]]1210; CGSCC: f:1211; CGSCC-NEXT: [[P:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[T]] ]1212; CGSCC-NEXT: [[RC1:%.*]] = call noundef i1 @ret(i1 noundef [[P]]) #[[ATTR12]]1213; CGSCC-NEXT: ret i1 [[RC1]]1214;1215entry:1216 br i1 %c, label %t, label %f1217t:1218 br label %f1219f:1220 %p = phi i1 [true, %entry], [false, %t]1221 %rc1 = call i1 @ret(i1 %p)1222 ret i1 %rc11223}1224 1225define internal i1 @ret(i1 %c) {1226; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1227; CGSCC-LABEL: define {{[^@]+}}@ret1228; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR1]] {1229; CGSCC-NEXT: entry:1230; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]1231; CGSCC: t:1232; CGSCC-NEXT: br label [[F]]1233; CGSCC: f:1234; CGSCC-NEXT: [[P:%.*]] = phi i1 [ [[C]], [[ENTRY:%.*]] ], [ false, [[T]] ]1235; CGSCC-NEXT: ret i1 false1236;1237entry:1238 br i1 %c, label %t, label %f1239t:1240 br label %f1241f:1242 %p = phi i1 [%c, %entry], [false, %t]1243 ret i1 %p1244}1245 1246declare ptr @unknown()1247define internal i8 @dead_ret() {1248; CHECK-LABEL: define {{[^@]+}}@dead_ret() {1249; CHECK-NEXT: [[R:%.*]] = call ptr @unknown()1250; CHECK-NEXT: ret i8 undef1251;1252 %r = call ptr @unknown()1253 %l = load i8, ptr %r1254 ret i8 %l1255}1256 1257define void @dead_ret_caller() {1258; CHECK-LABEL: define {{[^@]+}}@dead_ret_caller() {1259; CHECK-NEXT: [[R:%.*]] = call i8 @dead_ret()1260; CHECK-NEXT: ret void1261;1262 %r = call i8 @dead_ret()1263 ret void1264}1265 1266declare void @llvm.memcpy(ptr %dest, ptr %src, i32 %len, i1 %isvolatile)1267define internal i8 @memcpy_uses_store(i8 %arg) {1268; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1269; TUNIT-LABEL: define {{[^@]+}}@memcpy_uses_store1270; TUNIT-SAME: (i8 [[ARG:%.*]]) #[[ATTR2]] {1271; TUNIT-NEXT: [[SRC:%.*]] = alloca i8, align 11272; TUNIT-NEXT: [[DST:%.*]] = alloca i8, align 11273; TUNIT-NEXT: store i8 [[ARG]], ptr [[SRC]], align 11274; TUNIT-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[DST]], ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR12:[0-9]+]]1275; TUNIT-NEXT: [[L:%.*]] = load i8, ptr [[DST]], align 11276; TUNIT-NEXT: ret i8 [[L]]1277;1278; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1279; CGSCC-LABEL: define {{[^@]+}}@memcpy_uses_store1280; CGSCC-SAME: (i8 [[ARG:%.*]]) #[[ATTR1]] {1281; CGSCC-NEXT: [[SRC:%.*]] = alloca i8, align 11282; CGSCC-NEXT: [[DST:%.*]] = alloca i8, align 11283; CGSCC-NEXT: store i8 [[ARG]], ptr [[SRC]], align 11284; CGSCC-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[DST]], ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR16:[0-9]+]]1285; CGSCC-NEXT: [[L:%.*]] = load i8, ptr [[DST]], align 11286; CGSCC-NEXT: ret i8 [[L]]1287;1288 %src = alloca i81289 %dst = alloca i81290 store i8 %arg, ptr %src1291 call void @llvm.memcpy(ptr %dst, ptr %src, i32 1, i1 false)1292 %l = load i8, ptr %dst1293 ret i8 %l1294}1295 1296define i8 @memcpy_uses_store_caller(i8 %arg) {1297; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1298; TUNIT-LABEL: define {{[^@]+}}@memcpy_uses_store_caller1299; TUNIT-SAME: (i8 [[ARG:%.*]]) #[[ATTR2]] {1300; TUNIT-NEXT: [[R:%.*]] = call i8 @memcpy_uses_store(i8 [[ARG]]) #[[ATTR13:[0-9]+]]1301; TUNIT-NEXT: ret i8 [[R]]1302;1303; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)1304; CGSCC-LABEL: define {{[^@]+}}@memcpy_uses_store_caller1305; CGSCC-SAME: (i8 [[ARG:%.*]]) #[[ATTR3]] {1306; CGSCC-NEXT: [[R:%.*]] = call i8 @memcpy_uses_store(i8 [[ARG]]) #[[ATTR12]]1307; CGSCC-NEXT: ret i8 [[R]]1308;1309 %r = call i8 @memcpy_uses_store(i8 %arg)1310 ret i8 %r1311}1312 1313 1314declare i32 @speculatable() speculatable readnone1315 1316define i32 @test_speculatable_expr() norecurse {1317; TUNIT: Function Attrs: norecurse nosync memory(none)1318; TUNIT-LABEL: define {{[^@]+}}@test_speculatable_expr1319; TUNIT-SAME: () #[[ATTR7:[0-9]+]] {1320; TUNIT-NEXT: [[STACK:%.*]] = alloca i32, align 41321; TUNIT-NEXT: [[SPEC_RESULT:%.*]] = call i32 @speculatable() #[[ATTR14:[0-9]+]]1322; TUNIT-NEXT: [[PLUS1:%.*]] = add i32 [[SPEC_RESULT]], 11323; TUNIT-NEXT: store i32 [[PLUS1]], ptr [[STACK]], align 41324; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[STACK]], align 41325; TUNIT-NEXT: [[RSPEC:%.*]] = call i32 @ret_speculatable_expr(i32 [[TMP1]]) #[[ATTR15:[0-9]+]]1326; TUNIT-NEXT: ret i32 [[RSPEC]]1327;1328; CGSCC: Function Attrs: norecurse nosync memory(none)1329; CGSCC-LABEL: define {{[^@]+}}@test_speculatable_expr1330; CGSCC-SAME: () #[[ATTR9:[0-9]+]] {1331; CGSCC-NEXT: [[STACK:%.*]] = alloca i32, align 41332; CGSCC-NEXT: [[SPEC_RESULT:%.*]] = call i32 @speculatable() #[[ATTR17:[0-9]+]]1333; CGSCC-NEXT: [[PLUS1:%.*]] = add i32 [[SPEC_RESULT]], 11334; CGSCC-NEXT: store i32 [[PLUS1]], ptr [[STACK]], align 41335; CGSCC-NEXT: [[RSPEC:%.*]] = call i32 @ret_speculatable_expr(i32 [[PLUS1]]) #[[ATTR17]]1336; CGSCC-NEXT: ret i32 [[RSPEC]]1337;1338 %stack = alloca i321339 %spec_result = call i32 @speculatable()1340 %plus1 = add i32 %spec_result, 11341 store i32 %plus1, ptr %stack1342 %rspec = call i32 @ret_speculatable_expr(ptr %stack, i32 13)1343 ret i32 %rspec1344}1345 1346define internal i32 @ret_speculatable_expr(ptr %mem, i32 %a2) {1347; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1348; TUNIT-LABEL: define {{[^@]+}}@ret_speculatable_expr1349; TUNIT-SAME: (i32 [[TMP0:%.*]]) #[[ATTR2]] {1350; TUNIT-NEXT: [[MEM_PRIV:%.*]] = alloca i32, align 41351; TUNIT-NEXT: store i32 [[TMP0]], ptr [[MEM_PRIV]], align 41352; TUNIT-NEXT: [[L:%.*]] = load i32, ptr [[MEM_PRIV]], align 41353; TUNIT-NEXT: [[MUL:%.*]] = mul i32 [[L]], 131354; TUNIT-NEXT: [[ADD:%.*]] = add i32 [[MUL]], 71355; TUNIT-NEXT: ret i32 [[ADD]]1356;1357; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1358; CGSCC-LABEL: define {{[^@]+}}@ret_speculatable_expr1359; CGSCC-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] {1360; CGSCC-NEXT: [[MEM_PRIV:%.*]] = alloca i32, align 41361; CGSCC-NEXT: store i32 [[TMP0]], ptr [[MEM_PRIV]], align 41362; CGSCC-NEXT: [[L:%.*]] = load i32, ptr [[MEM_PRIV]], align 41363; CGSCC-NEXT: [[MUL:%.*]] = mul i32 [[L]], 131364; CGSCC-NEXT: [[ADD:%.*]] = add i32 [[MUL]], 71365; CGSCC-NEXT: ret i32 [[ADD]]1366;1367 %l = load i32, ptr %mem1368 %mul = mul i32 %l, %a21369 %add = add i32 %mul, 71370 ret i32 %add1371}1372 1373define internal void @not_called1() {1374; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1375; TUNIT-LABEL: define {{[^@]+}}@not_called11376; TUNIT-SAME: () #[[ATTR2]] {1377; TUNIT-NEXT: ret void1378;1379; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1380; CGSCC-LABEL: define {{[^@]+}}@not_called11381; CGSCC-SAME: () #[[ATTR1]] {1382; CGSCC-NEXT: ret void1383;1384 ret void1385}1386define internal void @not_called2() {1387; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1388; TUNIT-LABEL: define {{[^@]+}}@not_called21389; TUNIT-SAME: () #[[ATTR2]] {1390; TUNIT-NEXT: ret void1391;1392; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1393; CGSCC-LABEL: define {{[^@]+}}@not_called21394; CGSCC-SAME: () #[[ATTR1]] {1395; CGSCC-NEXT: ret void1396;1397 ret void1398}1399define internal void @not_called3() {1400; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1401; CGSCC-LABEL: define {{[^@]+}}@not_called31402; CGSCC-SAME: () #[[ATTR1]] {1403; CGSCC-NEXT: ret void1404;1405 ret void1406}1407declare void @useFnDecl(ptr addrspace(42));1408define void @useFnDef(ptr addrspace(42) %arg) {1409; CHECK-LABEL: define {{[^@]+}}@useFnDef1410; CHECK-SAME: (ptr addrspace(42) [[ARG:%.*]]) {1411; CHECK-NEXT: call void @useFnDecl(ptr addrspace(42) [[ARG]])1412; CHECK-NEXT: ret void1413;1414 call void @useFnDecl(ptr addrspace(42) %arg)1415 ret void1416}1417define i1 @user_of_not_called() {1418; CHECK-LABEL: define {{[^@]+}}@user_of_not_called() {1419; CHECK-NEXT: call void @useFnDecl(ptr addrspace(42) noundef nonnull addrspacecast (ptr @not_called1 to ptr addrspace(42)))1420; CHECK-NEXT: call void @useFnDef(ptr addrspace(42) noundef nonnull addrspacecast (ptr @not_called2 to ptr addrspace(42)))1421; CHECK-NEXT: ret i1 false1422;1423 call void @useFnDecl(ptr addrspace(42) addrspacecast (ptr @not_called1 to ptr addrspace(42)))1424 call void @useFnDef(ptr addrspace(42) addrspacecast (ptr @not_called2 to ptr addrspace(42)))1425 %cmp = icmp eq ptr addrspace(42) addrspacecast (ptr @not_called3 to ptr addrspace(42)), null1426 ret i1 %cmp1427}1428 1429@x = external global i321430define internal void @indirect() {1431; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)1432; TUNIT-LABEL: define {{[^@]+}}@indirect1433; TUNIT-SAME: () #[[ATTR5]] {1434; TUNIT-NEXT: store i32 0, ptr @x, align 41435; TUNIT-NEXT: ret void1436;1437; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)1438; CGSCC-LABEL: define {{[^@]+}}@indirect1439; CGSCC-SAME: () #[[ATTR10:[0-9]+]] {1440; CGSCC-NEXT: store i32 0, ptr @x, align 41441; CGSCC-NEXT: ret void1442;1443 store i32 0, ptr @x1444 ret void1445}1446 1447define internal void @broker(ptr %ptr) {1448; TUNIT: Function Attrs: memory(readwrite, argmem: none)1449; TUNIT-LABEL: define {{[^@]+}}@broker1450; TUNIT-SAME: () #[[ATTR1]] {1451; TUNIT-NEXT: entry:1452; TUNIT-NEXT: call void @indirect() #[[ATTR16:[0-9]+]]1453; TUNIT-NEXT: call void @unknown()1454; TUNIT-NEXT: ret void1455;1456; CGSCC: Function Attrs: memory(readwrite, argmem: none)1457; CGSCC-LABEL: define {{[^@]+}}@broker1458; CGSCC-SAME: () #[[ATTR2]] {1459; CGSCC-NEXT: entry:1460; CGSCC-NEXT: call void @indirect() #[[ATTR18:[0-9]+]]1461; CGSCC-NEXT: call void @unknown()1462; CGSCC-NEXT: ret void1463;1464entry:1465 call void %ptr()1466 call void @unknown()1467 ret void1468}1469 1470define void @entry() {1471; CHECK-LABEL: define {{[^@]+}}@entry() {1472; CHECK-NEXT: entry:1473; CHECK-NEXT: call void @broker()1474; CHECK-NEXT: ret void1475;1476entry:1477 call void @broker(ptr @indirect)1478 ret void1479}1480 1481define i8 @switch(i1 %c1, i1 %c2) {1482; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1483; TUNIT-LABEL: define {{[^@]+}}@switch1484; TUNIT-SAME: (i1 noundef [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR2]] {1485; TUNIT-NEXT: entry:1486; TUNIT-NEXT: br i1 [[C1]], label [[T:%.*]], label [[F:%.*]]1487; TUNIT: t:1488; TUNIT-NEXT: br label [[M:%.*]]1489; TUNIT: f:1490; TUNIT-NEXT: br label [[M]]1491; TUNIT: m:1492; TUNIT-NEXT: [[J:%.*]] = phi i32 [ 0, [[T]] ], [ 4, [[F]] ]1493; TUNIT-NEXT: switch i32 [[J]], label [[DEFAULT1:%.*]] [1494; TUNIT-NEXT: i32 1, label [[DEAD1:%.*]]1495; TUNIT-NEXT: i32 2, label [[DEAD2:%.*]]1496; TUNIT-NEXT: i32 3, label [[DEAD3:%.*]]1497; TUNIT-NEXT: i32 4, label [[ALIVE1:%.*]]1498; TUNIT-NEXT: ]1499; TUNIT: default1:1500; TUNIT-NEXT: br label [[ALIVE1]]1501; TUNIT: alive1:1502; TUNIT-NEXT: [[K:%.*]] = phi i32 [ 1, [[M]] ], [ 4, [[DEFAULT1]] ]1503; TUNIT-NEXT: switch i32 [[K]], label [[DEAD4:%.*]] [1504; TUNIT-NEXT: i32 1, label [[END1:%.*]]1505; TUNIT-NEXT: i32 2, label [[DEAD5:%.*]]1506; TUNIT-NEXT: i32 4, label [[END2:%.*]]1507; TUNIT-NEXT: ]1508; TUNIT: end1:1509; TUNIT-NEXT: ret i8 -11510; TUNIT: end2:1511; TUNIT-NEXT: ret i8 -21512; TUNIT: dead1:1513; TUNIT-NEXT: unreachable1514; TUNIT: dead2:1515; TUNIT-NEXT: unreachable1516; TUNIT: dead3:1517; TUNIT-NEXT: unreachable1518; TUNIT: dead4:1519; TUNIT-NEXT: unreachable1520; TUNIT: dead5:1521; TUNIT-NEXT: unreachable1522;1523; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1524; CGSCC-LABEL: define {{[^@]+}}@switch1525; CGSCC-SAME: (i1 noundef [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR1]] {1526; CGSCC-NEXT: entry:1527; CGSCC-NEXT: br i1 [[C1]], label [[T:%.*]], label [[F:%.*]]1528; CGSCC: t:1529; CGSCC-NEXT: br label [[M:%.*]]1530; CGSCC: f:1531; CGSCC-NEXT: br label [[M]]1532; CGSCC: m:1533; CGSCC-NEXT: [[J:%.*]] = phi i32 [ 0, [[T]] ], [ 4, [[F]] ]1534; CGSCC-NEXT: switch i32 [[J]], label [[DEFAULT1:%.*]] [1535; CGSCC-NEXT: i32 1, label [[DEAD1:%.*]]1536; CGSCC-NEXT: i32 2, label [[DEAD2:%.*]]1537; CGSCC-NEXT: i32 3, label [[DEAD3:%.*]]1538; CGSCC-NEXT: i32 4, label [[ALIVE1:%.*]]1539; CGSCC-NEXT: ]1540; CGSCC: default1:1541; CGSCC-NEXT: br label [[ALIVE1]]1542; CGSCC: alive1:1543; CGSCC-NEXT: [[K:%.*]] = phi i32 [ 1, [[M]] ], [ 4, [[DEFAULT1]] ]1544; CGSCC-NEXT: switch i32 [[K]], label [[DEAD4:%.*]] [1545; CGSCC-NEXT: i32 1, label [[END1:%.*]]1546; CGSCC-NEXT: i32 2, label [[DEAD5:%.*]]1547; CGSCC-NEXT: i32 4, label [[END2:%.*]]1548; CGSCC-NEXT: ]1549; CGSCC: end1:1550; CGSCC-NEXT: ret i8 -11551; CGSCC: end2:1552; CGSCC-NEXT: ret i8 -21553; CGSCC: dead1:1554; CGSCC-NEXT: unreachable1555; CGSCC: dead2:1556; CGSCC-NEXT: unreachable1557; CGSCC: dead3:1558; CGSCC-NEXT: unreachable1559; CGSCC: dead4:1560; CGSCC-NEXT: unreachable1561; CGSCC: dead5:1562; CGSCC-NEXT: unreachable1563;1564entry:1565 br i1 %c1, label %t, label %f1566 1567t:1568 br label %m1569 1570f:1571 br label %m1572 1573m:1574 %j = phi i32 [ 0, %t ], [ 4, %f ]1575 switch i32 %j, label %default1 [1576 i32 1, label %dead11577 i32 2, label %dead21578 i32 3, label %dead31579 i32 4, label %alive11580 ]1581 1582default1:1583 br label %alive11584 1585alive1:1586 %k = phi i32 [ 1, %m ], [ 4, %default1 ]1587 switch i32 %k, label %dead4 [1588 i32 1, label %end11589 i32 2, label %dead51590 i32 4, label %end21591 ]1592 1593end1:1594 ret i8 -11595end2:1596 ret i8 -21597dead1:1598 ret i8 11599dead2:1600 ret i8 21601dead3:1602 ret i8 31603dead4:1604 ret i8 41605dead5:1606 ret i8 51607}1608 1609define i32 @readConst() {1610; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1611; TUNIT-LABEL: define {{[^@]+}}@readConst1612; TUNIT-SAME: () #[[ATTR2]] {1613; TUNIT-NEXT: ret i32 01614;1615; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1616; CGSCC-LABEL: define {{[^@]+}}@readConst1617; CGSCC-SAME: () #[[ATTR1]] {1618; CGSCC-NEXT: ret i32 01619;1620 %l = load i32, ptr @ConstPtr1621 ret i32 %l1622}1623 1624define i32 @readWeakConst() {1625; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1626; TUNIT-LABEL: define {{[^@]+}}@readWeakConst1627; TUNIT-SAME: () #[[ATTR2]] {1628; TUNIT-NEXT: [[L:%.*]] = load i32, ptr @ConstWeakPtr, align 41629; TUNIT-NEXT: ret i32 [[L]]1630;1631; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1632; CGSCC-LABEL: define {{[^@]+}}@readWeakConst1633; CGSCC-SAME: () #[[ATTR1]] {1634; CGSCC-NEXT: [[L:%.*]] = load i32, ptr @ConstWeakPtr, align 41635; CGSCC-NEXT: ret i32 [[L]]1636;1637 %l = load i32, ptr @ConstWeakPtr1638 ret i32 %l1639}1640 1641define i32 @readWeakOdrConst() {1642; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1643; TUNIT-LABEL: define {{[^@]+}}@readWeakOdrConst1644; TUNIT-SAME: () #[[ATTR2]] {1645; TUNIT-NEXT: ret i32 01646;1647; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1648; CGSCC-LABEL: define {{[^@]+}}@readWeakOdrConst1649; CGSCC-SAME: () #[[ATTR1]] {1650; CGSCC-NEXT: ret i32 01651;1652 %l = load i32, ptr @ConstWeakODRPtr1653 ret i32 %l1654}1655 1656define i32 @readExtInitZeroInit() {1657; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1658; TUNIT-LABEL: define {{[^@]+}}@readExtInitZeroInit1659; TUNIT-SAME: () #[[ATTR2]] {1660; TUNIT-NEXT: [[L:%.*]] = load i32, ptr @ExtInitZeroInit, align 41661; TUNIT-NEXT: ret i32 [[L]]1662;1663; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1664; CGSCC-LABEL: define {{[^@]+}}@readExtInitZeroInit1665; CGSCC-SAME: () #[[ATTR1]] {1666; CGSCC-NEXT: [[L:%.*]] = load i32, ptr @ExtInitZeroInit, align 41667; CGSCC-NEXT: ret i32 [[L]]1668;1669 %l = load i32, ptr @ExtInitZeroInit1670 ret i32 %l1671}1672 1673;.1674; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn }1675; TUNIT: attributes #[[ATTR1]] = { memory(readwrite, argmem: none) }1676; TUNIT: attributes #[[ATTR2]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }1677; TUNIT: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind willreturn }1678; TUNIT: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }1679; TUNIT: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }1680; TUNIT: attributes #[[ATTR6:[0-9]+]] = { speculatable memory(none) }1681; TUNIT: attributes #[[ATTR7]] = { norecurse nosync memory(none) }1682; TUNIT: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }1683; TUNIT: attributes #[[ATTR9]] = { nofree nosync nounwind willreturn memory(none) }1684; TUNIT: attributes #[[ATTR10]] = { nofree willreturn }1685; TUNIT: attributes #[[ATTR11]] = { nofree nosync nounwind willreturn memory(write) }1686; TUNIT: attributes #[[ATTR12]] = { nofree willreturn memory(readwrite) }1687; TUNIT: attributes #[[ATTR13]] = { nofree nosync nounwind willreturn }1688; TUNIT: attributes #[[ATTR14]] = { nosync }1689; TUNIT: attributes #[[ATTR15]] = { nosync nounwind memory(read) }1690; TUNIT: attributes #[[ATTR16]] = { nounwind memory(write) }1691;.1692; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn }1693; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }1694; CGSCC: attributes #[[ATTR2]] = { memory(readwrite, argmem: none) }1695; CGSCC: attributes #[[ATTR3]] = { mustprogress nofree nosync nounwind willreturn memory(none) }1696; CGSCC: attributes #[[ATTR4]] = { mustprogress nofree nosync nounwind willreturn }1697; CGSCC: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }1698; CGSCC: attributes #[[ATTR6]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: write) }1699; CGSCC: attributes #[[ATTR7]] = { mustprogress nofree nosync nounwind willreturn memory(write) }1700; CGSCC: attributes #[[ATTR8:[0-9]+]] = { speculatable memory(none) }1701; CGSCC: attributes #[[ATTR9]] = { norecurse nosync memory(none) }1702; CGSCC: attributes #[[ATTR10]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }1703; CGSCC: attributes #[[ATTR11:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }1704; CGSCC: attributes #[[ATTR12]] = { nofree nosync willreturn }1705; CGSCC: attributes #[[ATTR13]] = { nofree willreturn }1706; CGSCC: attributes #[[ATTR14]] = { nofree nounwind willreturn }1707; CGSCC: attributes #[[ATTR15]] = { nofree nounwind willreturn memory(write) }1708; CGSCC: attributes #[[ATTR16]] = { nofree willreturn memory(readwrite) }1709; CGSCC: attributes #[[ATTR17]] = { nosync }1710; CGSCC: attributes #[[ATTR18]] = { nounwind }1711;.1712