766 lines · plain
1; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=inline-call-sites -reduce-callsite-inline-threshold=-1 --test FileCheck --test-arg --check-prefixes=CHECK,INTERESTING --test-arg %s --test-arg --input-file %s -o %t2; RUN: FileCheck -check-prefixes=RESULT,CHECK %s < %t3 4; RESULT: @gv = global [2 x ptr] [ptr @only_gv_user, ptr @simple_callee]5@gv = global [2 x ptr] [ptr @only_gv_user, ptr @simple_callee]6 7; RESULT: @indirectbr.L = internal unnamed_addr constant [3 x ptr] [ptr blockaddress(@callee_with_indirectbr, %L1), ptr blockaddress(@callee_with_indirectbr, %L2), ptr null], align 88@indirectbr.L = internal unnamed_addr constant [3 x ptr] [ptr blockaddress(@callee_with_indirectbr, %L1), ptr blockaddress(@callee_with_indirectbr, %L2), ptr null], align 89 10 11; CHECK-LABEL: define void @simple_callee(12; RESULT-NEXT: store i32 123, ptr %arg, align 413; RESULT-NEXT: ret void14define void @simple_callee(ptr %arg) {15 store i32 123, ptr %arg16 ret void17}18 19; CHECK-LABEL: define void @simple_caller(20; RESULT-NEXT: store i32 123, ptr %outer.arg, align 421; RESULT-NEXT: ret void22define void @simple_caller(ptr %outer.arg) {23 call void @simple_callee(ptr %outer.arg)24 ret void25}26 27; CHECK-LABEL: define void @multi_simple_caller(28; RESULT-NEXT: store i32 123, ptr %outer.arg, align 429; RESULT-NEXT: store i32 123, ptr %outer.arg, align 430; RESULT-NEXT: store i32 123, ptr null, align 431; RESULT-NEXT: ret void32define void @multi_simple_caller(ptr %outer.arg) {33 call void @simple_callee(ptr %outer.arg)34 call void @simple_callee(ptr %outer.arg)35 call void @simple_callee(ptr null)36 ret void37}38 39; CHECK-LABEL: define void @only_gv_user(40; RESULT-NEXT: store i32 666, ptr %arg, align 441; RESULT-NEXT: ret void42define void @only_gv_user(ptr %arg) {43 store i32 666, ptr %arg44 ret void45}46 47; CHECK-LABEL: define void @recursive(48; RESULT-NEXT: call void @recursive(ptr %arg)49; RESULT-NEXT: ret void50define void @recursive(ptr %arg) {51 call void @recursive(ptr %arg)52 ret void53}54 55; CHECK-LABEL: define void @recursive_with_wrong_callsite_type(56; RESULT-NEXT: call void @recursive_with_wrong_callsite_type(ptr %arg, i32 2)57; RESULT-NEXT: ret void58define void @recursive_with_wrong_callsite_type(ptr %arg) {59 call void @recursive_with_wrong_callsite_type(ptr %arg, i32 2)60 ret void61}62 63; CHECK-LABEL: define void @non_callee_use(64; RESULT-NEXT: store i32 567, ptr %arg, align 465; RESULT-NEXT: ret void66define void @non_callee_use(ptr %arg) {67 store i32 567, ptr %arg68 ret void69}70 71declare void @extern_ptr_use(ptr)72 73; CHECK-LABEL: define void @non_callee_user(74; RESULT-NEXT: call void @extern_ptr_use(ptr @non_callee_use)75; RESULT-NEXT: ret void76define void @non_callee_user() {77 call void @extern_ptr_use(ptr @non_callee_use)78 ret void79}80 81; CHECK-LABEL: define void @non_call_inst_use(82define void @non_call_inst_use(ptr %arg) {83 store i32 999, ptr %arg84 ret void85}86 87; CHECK-LABEL: define void @non_call_inst_user(88; RESULT-NEXT: store ptr @non_call_inst_use, ptr %arg, align 889; RESULT-NEXT: ret void90define void @non_call_inst_user(ptr %arg) {91 store ptr @non_call_inst_use, ptr %arg92 ret void93}94 95; CHECK-LABEL: define i32 @used_wrong_call_type(96; RESULT-NEXT: store i32 123, ptr %arg, align 497; RESULT-NEXT: ret i32 898define i32 @used_wrong_call_type(ptr %arg) {99 store i32 123, ptr %arg100 ret i32 8101}102 103; Inlining doesn't support the UB cases104; CHECK-LABEL: define void @use_wrong_call_type(105; RESULT-NEXT: call void @used_wrong_call_type(ptr %outer.arg)106; RESULT-NEXT: ret void107define void @use_wrong_call_type(ptr %outer.arg) {108 call void @used_wrong_call_type(ptr %outer.arg)109 ret void110}111 112; INTERESTING-LABEL: define void @incompatible_gc_callee(113 114; RESULT-LABEL: define void @incompatible_gc_callee(ptr %arg) gc "gc0" {115; RESULT-NEXT: store i32 10000, ptr %arg, align 4116; RESULT-NEXT: ret void117define void @incompatible_gc_callee(ptr %arg) gc "gc0" {118 store i32 10000, ptr %arg119 ret void120}121 122; INTERESTING-LABEL: define void @incompatible_gc_caller(123 124; RESULT-LABEL: define void @incompatible_gc_caller(ptr %outer.arg) gc "gc1" {125; RESULT-NEXT: call void @incompatible_gc_callee(ptr %outer.arg)126; RESULT-NEXT: ret void127define void @incompatible_gc_caller(ptr %outer.arg) gc "gc1" {128 call void @incompatible_gc_callee(ptr %outer.arg)129 ret void130}131 132; INTERESTING-LABEL: define void @propagate_callee_gc(133 134; RESULT-LABEL: define void @propagate_callee_gc(ptr %arg) gc "propagate-gc" {135; RESULT-NEXT: store i32 10000, ptr %arg, align 4136; RESULT-NEXT: ret void137define void @propagate_callee_gc(ptr %arg) gc "propagate-gc" {138 store i32 10000, ptr %arg139 ret void140}141 142; INTERESTING-LABEL: define void @propagate_caller_gc(143 144; RESULT-LABEL: define void @propagate_caller_gc(ptr %arg) gc "propagate-gc" {145; RESULT-NEXT: store i32 10000, ptr %arg, align 4146; RESULT-NEXT: ret void147define void @propagate_caller_gc(ptr %arg) {148 call void @propagate_callee_gc(ptr %arg)149 ret void150}151 152declare i32 @__gxx_personality_v0(...)153 154; INTERESTING-LABEL: define void @propagate_callee_personality(155 156; RESULT-LABEL: define void @propagate_callee_personality(ptr %arg) personality ptr @__gxx_personality_v0 {157; RESULT-NEXT: store i32 2000, ptr %arg, align 4158; RESULT-NEXT: ret void159define void @propagate_callee_personality(ptr %arg) personality ptr @__gxx_personality_v0 {160 store i32 2000, ptr %arg161 ret void162}163 164; INTERESTING-LABEL: define void @propagate_caller_personality(165 166; RESULT-LABEL: define void @propagate_caller_personality(ptr %arg) personality ptr @__gxx_personality_v0 {167; RESULT-NEXT: store i32 2000, ptr %arg, align 4168; RESULT-NEXT: ret void169define void @propagate_caller_personality(ptr %arg) {170 call void @propagate_callee_personality(ptr %arg)171 ret void172}173 174; CHECK-LABEL: define void @callee_with_indirectbr(175define void @callee_with_indirectbr() {176entry:177 br label %L1178 179L1: ; preds = %entry, %L1180 %i = phi i32 [ 0, %entry ], [ %inc, %L1 ]181 %inc = add i32 %i, 1182 %idxprom = zext i32 %i to i64183 %arrayidx = getelementptr inbounds [3 x ptr], ptr @indirectbr.L, i64 0, i64 %idxprom184 %brtarget = load ptr, ptr %arrayidx, align 8185 indirectbr ptr %brtarget, [label %L1, label %L2]186 187L2: ; preds = %L1188 ret void189}190 191; CHECK-LABEL: define void @calls_func_with_indirectbr(192 193; RESULT: L1.i:194; RESULT-NEXT: %i.i = phi i32 [ 0, %call ], [ %inc.i, %L1.i ]195; RESULT-NEXT: %inc.i = add i32 %i.i, 1196; RESULT-NEXT: %idxprom.i = zext i32 %i.i to i64197; RESULT-NEXT: %arrayidx.i = getelementptr inbounds [3 x ptr], ptr @indirectbr.L, i64 0, i64 %idxprom.i198; RESULT-NEXT: %brtarget.i = load ptr, ptr %arrayidx.i, align 8199; RESULT-NEXT: indirectbr ptr %brtarget.i, [label %L1.i, label %callee_with_indirectbr.exit]200 201define void @calls_func_with_indirectbr(i1 %arg0) {202entry:203 br i1 %arg0, label %call, label %ret204 205call:206 call void @callee_with_indirectbr()207 br label %ret208 209ret:210 ret void211}212 213 214; CHECK-LABEL: define ptr @callee_with_blockaddress_use(215; RESULT: L2:216; RESULT-NEXT: store ptr blockaddress(@callee_with_blockaddress_use, %L1), ptr %alloca, align 8217; RESULT-NEXT: store ptr blockaddress(@callee_with_blockaddress_use, %L2), ptr %alloca, align 8218; RESULT-NEXT: store ptr blockaddress(@callee_with_blockaddress_use, %L3), ptr %alloca, align 8219; RESULT-NEXT: %cond1 = load volatile i1, ptr addrspace(1) null220; RESULT-NEXT: br i1 %cond1, label %L1, label %L3221define ptr @callee_with_blockaddress_use() {222entry:223 %alloca = alloca ptr224 %cond0 = load volatile i1, ptr addrspace(1) null225 br i1 %cond0, label %L1, label %L2226 227L1:228 br label %L2229 230L2:231 ; reference an earlier block232 store ptr blockaddress(@callee_with_blockaddress_use, %L1), ptr %alloca233 234 ; reference the block itself from the block235 store ptr blockaddress(@callee_with_blockaddress_use, %L2), ptr %alloca236 237 ; reference a later block238 store ptr blockaddress(@callee_with_blockaddress_use, %L3), ptr %alloca239 240 %cond1 = load volatile i1, ptr addrspace(1) null241 br i1 %cond1, label %L1, label %L3242 243L3:244 %load = load ptr, ptr %alloca245 ret ptr %load246}247 248; FIXME: This is not correctly remapping the blockaddress use249; CHECK-LABEL: define void @calls_func_with_blockaddress_use(250; RESULT: entry:251; RESULT-NEXT: %alloca.i = alloca ptr, align 8252; RESULT-NEXT: store i32 1000, ptr null, align 4253; RESULT-NEXT: br i1 %arg0, label %call, label %ret254 255; RESULT: call:256; RESULT-NEXT: store i32 2000, ptr null, align 4257; RESULT-NEXT: call void @llvm.lifetime.start.p0(ptr %alloca.i)258; RESULT-NEXT: %cond0.i = load volatile i1, ptr addrspace(1) null, align 1259; RESULT-NEXT: br i1 %cond0.i, label %L1.i, label %L2.i260 261; RESULT: L1.i: ; preds = %L2.i, %call262; RESULT-NEXT: br label %L2.i263 264; RESULT: L2.i: ; preds = %L1.i, %call265; RESULT-NEXT: store ptr blockaddress(@callee_with_blockaddress_use, %L1), ptr %alloca.i, align 8266; RESULT-NEXT: store ptr blockaddress(@calls_func_with_blockaddress_use, %L2.i), ptr %alloca.i, align 8267; RESULT-NEXT: store ptr blockaddress(@callee_with_blockaddress_use, %L3), ptr %alloca.i, align 8268; RESULT-NEXT: %cond1.i = load volatile i1, ptr addrspace(1) null, align 1269; RESULT-NEXT: br i1 %cond1.i, label %L1.i, label %callee_with_blockaddress_use.exit270 271; RESULT: callee_with_blockaddress_use.exit: ; preds = %L2.i272; RESULT-NEXT: %load.i = load ptr, ptr %alloca.i, align 8273; RESULT-NEXT: call void @llvm.lifetime.end.p0(ptr %alloca.i)274; RESULT-NEXT: store i32 3000, ptr null, align 4275; RESULT-NEXT: br label %ret276 277; RESULT: ret: ; preds = %callee_with_blockaddress_use.exit, %entry278; RESULT-NEXT: store i32 4000, ptr null, align 4279; RESULT-NEXT: ret void280define void @calls_func_with_blockaddress_use(i1 %arg0) {281entry:282 store i32 1000, ptr null283 br i1 %arg0, label %call, label %ret284 285call:286 store i32 2000, ptr null287 call ptr @callee_with_blockaddress_use()288 store i32 3000, ptr null289 br label %ret290 291ret:292 store i32 4000, ptr null293 ret void294}295 296; CHECK-LABEL: define void @callee_with_fallthrough_blockaddress_use(297; RESULT: L2:298; RESULT-NEXT: store ptr blockaddress(@callee_with_fallthrough_blockaddress_use, %L1), ptr %alloca, align 8299; RESULT-NEXT: store ptr blockaddress(@callee_with_fallthrough_blockaddress_use, %L2), ptr %alloca, align 8300; RESULT-NEXT: store ptr blockaddress(@callee_with_fallthrough_blockaddress_use, %L3), ptr %alloca, align 8301; RESULT-NEXT: br label %L3302define void @callee_with_fallthrough_blockaddress_use() {303entry:304 %alloca = alloca ptr305 br label %L1306 307L1:308 store i32 999, ptr null309 br label %L2310 311L2: ; preds = %entry, %L1312 ; reference a block before this block313 store ptr blockaddress(@callee_with_fallthrough_blockaddress_use, %L1), ptr %alloca314 315 ; reference the block itself from the block316 store ptr blockaddress(@callee_with_fallthrough_blockaddress_use, %L2), ptr %alloca317 318 ; reference a block after this block319 store ptr blockaddress(@callee_with_fallthrough_blockaddress_use, %L3), ptr %alloca320 br label %L3321 322L3: ; preds = %L1323 %load = load ptr, ptr %alloca324 ret void325}326 327 328; CHECK-LABEL: define void @calls_func_with_fallthrough_blockaddress_use(329; RESULT: entry:330; RESULT-NEXT: %alloca.i = alloca ptr, align 8331; RESULT-NEXT: store i32 1000, ptr null332; RESULT-NEXT: br i1 %arg0, label %call, label %ret333 334; RESULT: call:335; RESULT-NEXT: store i32 2000, ptr null, align 4336; RESULT-NEXT: call void @llvm.lifetime.start.p0(ptr %alloca.i)337; RESULT-NEXT: br label %L1.i338 339; RESULT: L1.i: ; preds = %call340; RESULT-NEXT: store i32 999, ptr null, align 4341; RESULT-NEXT: br label %L2.i342 343; RESULT: L2.i:344; RESULT-NEXT: store ptr blockaddress(@calls_func_with_fallthrough_blockaddress_use, %L1.i), ptr %alloca.i, align 8345; RESULT-NEXT: store ptr blockaddress(@calls_func_with_fallthrough_blockaddress_use, %L2.i), ptr %alloca.i, align 8346; RESULT-NEXT: store ptr blockaddress(@callee_with_fallthrough_blockaddress_use, %L3), ptr %alloca.i, align 8347; RESULT-NEXT: br label %callee_with_fallthrough_blockaddress_use.exit348 349; RESULT: callee_with_fallthrough_blockaddress_use.exit: ; preds = %L2.i350; RESULT-NEXT: %load.i = load ptr, ptr %alloca.i, align 8351; RESULT-NEXT: call void @llvm.lifetime.end.p0(ptr %alloca.i)352; RESULT-NEXT: store i32 3000, ptr null, align 4353; RESULT-NEXT: br label %ret354 355; RESULT: ret:356; RESULT-NEXT: store i32 4000, ptr null, align 4357; RESULT-NEXT: ret void358define void @calls_func_with_fallthrough_blockaddress_use(i1 %arg0) {359entry:360 store i32 1000, ptr null361 br i1 %arg0, label %call, label %ret362 363call:364 store i32 2000, ptr null365 call void @callee_with_fallthrough_blockaddress_use()366 store i32 3000, ptr null367 br label %ret368 369ret:370 store i32 4000, ptr null371 ret void372}373 374declare i32 @extern_returns_twice() returns_twice375 376; CHECK-LABEL: define i32 @callee_returns_twice(377; RESULT-NEXT: %call = call i32 @extern_returns_twice()378; RESULT-NEXT: %add = add nsw i32 1, %call379; RESULT-NEXT: ret i32 %add380define i32 @callee_returns_twice() {381 %call = call i32 @extern_returns_twice()382 %add = add nsw i32 1, %call383 ret i32 %add384}385 386; CHECK-LABEL: define i32 @caller_returns_twice_calls_callee_returns_twice(387; RESULT-NEXT: %call.i = call i32 @extern_returns_twice()388; RESULT-NEXT: %add.i = add nsw i32 1, %call.i389; RESULT-NEXT: %add = add nsw i32 1, %add.i390; RESULT-NEXT: ret i32 %add391 define i32 @caller_returns_twice_calls_callee_returns_twice() returns_twice {392 %call = call i32 @callee_returns_twice()393 %add = add nsw i32 1, %call394 ret i32 %add395}396 397; Inliner usually blocks inlining of returns_twice functions into398; non-returns_twice functions399; CHECK-LABEL: define i32 @regular_caller_calls_callee_returns_twice() {400; RESULT-NEXT: %call.i = call i32 @extern_returns_twice()401; RESULT-NEXT: %add.i = add nsw i32 1, %call.i402; RESULT-NEXT: %add = add nsw i32 1, %add.i403; RESULT-NEXT: ret i32 %add404define i32 @regular_caller_calls_callee_returns_twice() {405 %call = call i32 @callee_returns_twice()406 %add = add nsw i32 1, %call407 ret i32 %add408}409 410; CHECK-LABEL: define void @caller_with_vastart(411; RESULT-NEXT: %ap = alloca ptr, align 4412; RESULT-NEXT: %ap2 = alloca ptr, align 4413; RESULT-NEXT: call void @llvm.va_start.p0(ptr nonnull %ap)414; RESULT-NEXT: call void @llvm.va_end.p0(ptr nonnull %ap)415; RESULT-NEXT: call void @llvm.va_start.p0(ptr nonnull %ap)416; RESULT-NEXT: call void @llvm.va_end.p0(ptr nonnull %ap)417; RESULT-NEXT: ret void418define void @caller_with_vastart(ptr noalias nocapture readnone %args, ...) {419 %ap = alloca ptr, align 4420 %ap2 = alloca ptr, align 4421 call void @llvm.va_start.p0(ptr nonnull %ap)422 call fastcc void @callee_with_vaend(ptr nonnull %ap)423 call void @llvm.va_start.p0(ptr nonnull %ap)424 call fastcc void @callee_with_vaend_alwaysinline(ptr nonnull %ap)425 ret void426}427 428; CHECK-LABEL: define fastcc void @callee_with_vaend(429; RESULT-NEXT: tail call void @llvm.va_end.p0(ptr %a)430; RESULT-NEXT: ret void431define fastcc void @callee_with_vaend(ptr %a) {432 tail call void @llvm.va_end.p0(ptr %a)433 ret void434}435 436; CHECK-LABEL: define internal fastcc void @callee_with_vaend_alwaysinline(437; RESULT-NEXT: tail call void @llvm.va_end.p0(ptr %a)438; RESULT-NEXT: ret void439define internal fastcc void @callee_with_vaend_alwaysinline(ptr %a) alwaysinline {440 tail call void @llvm.va_end.p0(ptr %a)441 ret void442}443 444; CHECK-LABEL: define i32 @callee_with_va_start(445define i32 @callee_with_va_start(ptr %a, ...) {446 %vargs = alloca ptr, align 8447 tail call void @llvm.va_start.p0(ptr %a)448 %va1 = va_arg ptr %vargs, i32449 call void @llvm.va_end(ptr %vargs)450 ret i32 %va1451}452 453; CHECK-LABEL: define i32 @callee_vastart_caller(454; RESULT-NEXT: %vargs.i = alloca ptr, align 8455; RESULT-NEXT: %ap = alloca ptr, align 4456; RESULT-NEXT: %b = load i32, ptr null, align 4457; RESULT-NEXT: call void @llvm.lifetime.start.p0(ptr %vargs.i)458; RESULT-NEXT: call void @llvm.va_start.p0(ptr nonnull %ap)459; RESULT-NEXT: %va1.i = va_arg ptr %vargs.i, i32460; RESULT-NEXT: call void @llvm.va_end.p0(ptr %vargs.i)461; RESULT-NEXT: call void @llvm.lifetime.end.p0(ptr %vargs.i)462; RESULT-NEXT: ret i32 %va1.i463define i32 @callee_vastart_caller(ptr noalias nocapture readnone %args, ...) {464 %ap = alloca ptr, align 4465 %b = load i32, ptr null466 %result = call i32 (ptr, ...) @callee_with_va_start(ptr nonnull %ap, i32 %b)467 ret i32 %result468}469 470declare void @llvm.localescape(...)471 472; CHECK-LABEL: define internal void @callee_uses_localrecover(473define internal void @callee_uses_localrecover(ptr %fp) {474 %a.i8 = call ptr @llvm.localrecover(ptr @callee_uses_localescape, ptr %fp, i32 0)475 store i32 42, ptr %a.i8476 ret void477}478 479; CHECK-LABEL: define i32 @callee_uses_localescape(480; RESULT-NEXT: %a = alloca i32, align 4481; RESULT-NEXT: call void (...) @llvm.localescape(ptr %a)482; RESULT-NEXT: %fp = call ptr @llvm.frameaddress.p0(i32 0)483; RESULT-NEXT: %a.i8.i = call ptr @llvm.localrecover(ptr @callee_uses_localescape, ptr %fp, i32 0)484; RESULT-NEXT: store i32 42, ptr %a.i8.i, align 4485; RESULT-NEXT: %r = load i32, ptr %a, align 4486; RESULT-NEXT: ret i32 %r487define i32 @callee_uses_localescape() alwaysinline {488 %a = alloca i32489 call void (...) @llvm.localescape(ptr %a)490 %fp = call ptr @llvm.frameaddress(i32 0)491 tail call void @callee_uses_localrecover(ptr %fp)492 %r = load i32, ptr %a493 ret i32 %r494}495 496; CHECK-LABEL: define i32 @callee_uses_localescape_caller(497; RESULT-NEXT: %a.i = alloca i32, align 4498; RESULT-NEXT: call void @llvm.lifetime.start.p0(ptr %a.i)499; RESULT-NEXT: call void (...) @llvm.localescape(ptr %a.i)500; RESULT-NEXT: %fp.i = call ptr @llvm.frameaddress.p0(i32 0)501; RESULT-NEXT: %a.i8.i.i = call ptr @llvm.localrecover(ptr @callee_uses_localescape, ptr %fp.i, i32 0)502; RESULT-NEXT: store i32 42, ptr %a.i8.i.i, align 4503; RESULT-NEXT: %r.i = load i32, ptr %a.i, align 4504; RESULT-NEXT: call void @llvm.lifetime.end.p0(ptr %a.i)505; RESULT-NEXT: ret i32 %r.i506define i32 @callee_uses_localescape_caller() {507 %r = tail call i32 @callee_uses_localescape()508 ret i32 %r509}510 511declare void @llvm.icall.branch.funnel(...)512 513; CHECK-LABEL: define void @callee_uses_branch_funnel(514; RESULT-NEXT: musttail call void (...) @llvm.icall.branch.funnel(...)515; RESULT-NEXT: ret void516define void @callee_uses_branch_funnel(...) {517 musttail call void (...) @llvm.icall.branch.funnel(...)518 ret void519}520 521; FIXME: This should fail the verifier after inlining522; CHECK-LABEL: define void @callee_branch_funnel_musttail_caller(523; RESULT-NEXT: call void (...) @llvm.icall.branch.funnel()524; RESULT-NEXT: ret void525define void @callee_branch_funnel_musttail_caller() {526 call void (...) @callee_uses_branch_funnel()527 ret void528}529 530; Ignore noinline on the callee function531; CHECK-LABEL: define void @noinline_callee(532; RESULT-NEXT: store i32 123, ptr %arg, align 4533; RESULT-NEXT: ret void534define void @noinline_callee(ptr %arg) {535 store i32 123, ptr %arg536 ret void537}538 539; CHECK-LABEL: define void @calls_noinline_func(540; RESULT-NEXT: store i32 123, ptr %outer.arg, align 4541; RESULT-NEXT: ret void542define void @calls_noinline_func(ptr %outer.arg) {543 call void @noinline_callee(ptr %outer.arg)544 ret void545}546 547; Ignore noinline on the callsite548; CHECK-LABEL: define void @calls_noinline_callsite(549; RESULT-NEXT: store i32 123, ptr %outer.arg, align 4550; RESULT-NEXT: ret void551define void @calls_noinline_callsite(ptr %outer.arg) {552 call void @simple_callee(ptr %outer.arg) noinline553 ret void554}555 556; Ignore optnone557; CHECK-LABEL: define void @optnone_callee(558; RESULT-NEXT: store i32 5555, ptr %arg, align 4559; RESULT-NEXT: ret void560define void @optnone_callee(ptr %arg) optnone noinline {561 store i32 5555, ptr %arg562 ret void563}564 565; CHECK-LABEL: define void @calls_optnone_callee(566; RESULT-NEXT: store i32 5555, ptr %outer.arg, align 4567; RESULT-NEXT: ret void568define void @calls_optnone_callee(ptr %outer.arg) {569 call void @optnone_callee(ptr %outer.arg)570 ret void571}572 573; CHECK-LABEL: define void @optnone_caller(574; RESULT-NEXT: store i32 123, ptr %outer.arg, align 4575; RESULT-NEXT: ret void576define void @optnone_caller(ptr %outer.arg) optnone noinline {577 call void @simple_callee(ptr %outer.arg)578 ret void579}580 581; CHECK-LABEL: define weak void @interposable_callee(582; RESULT-NEXT: store i32 2024, ptr %arg, align 4583; RESULT-NEXT: ret void584define weak void @interposable_callee(ptr %arg) {585 store i32 2024, ptr %arg586 ret void587}588 589; Ignore interposable linkage590; CHECK-LABEL: @calls_interposable_callee(591; RESULT-NEXT: store i32 2024, ptr %arg, align 4592; RESULT-NEXT: ret void593define void @calls_interposable_callee(ptr %arg) {594 call void @interposable_callee(ptr %arg)595 ret void596}597 598; Ignore null_pointer_is_valid599; CHECK-LABEL: @null_pointer_is_valid_callee(600; RESULT-NEXT: store i32 42069, ptr %arg, align 4601; RESULT-NEXT: ret void602define void @null_pointer_is_valid_callee(ptr %arg) null_pointer_is_valid {603 store i32 42069, ptr %arg604 ret void605}606 607; CHECK-LABEL: @calls_null_pointer_is_valid_callee(608; RESULT-NEXT: store i32 42069, ptr %arg, align 4609; RESULT-NEXT: ret void610define void @calls_null_pointer_is_valid_callee(ptr %arg) {611 call void @null_pointer_is_valid_callee(ptr %arg)612 ret void613}614 615; CHECK-LABEL: @byval_arg_uses_non_alloca_addrspace(616; RESULT-NEXT: %load = load i32, ptr addrspace(1) %arg, align 4617; RESULT-NEXT: ret i32 %load618define i32 @byval_arg_uses_non_alloca_addrspace(ptr addrspace(1) byval(i32) %arg) {619 %load = load i32, ptr addrspace(1) %arg620 ret i32 %load621}622 623; CHECK-LABEL: @calls_byval_arg_uses_non_alloca_addrspace(624; RESULT-NEXT: %arg1 = alloca i32, align 4, addrspace(1)625; RESULT-NEXT: call void @llvm.lifetime.start.p1(ptr addrspace(1) %arg1)626; RESULT-NEXT: call void @llvm.memcpy.p1.p1.i64(ptr addrspace(1) align 4 %arg1, ptr addrspace(1) %arg, i64 4, i1 false)627; RESULT-NEXT: %load.i = load i32, ptr addrspace(1) %arg1, align 4628; RESULT-NEXT: call void @llvm.lifetime.end.p1(ptr addrspace(1) %arg1)629; RESULT-NEXT: ret i32 %load.i630define i32 @calls_byval_arg_uses_non_alloca_addrspace(ptr addrspace(1) %arg) {631 %call = call i32 @byval_arg_uses_non_alloca_addrspace(ptr addrspace(1) byval(i32) %arg)632 ret i32 %call633}634 635; CHECK-LABEL: define void @callee_stacksize(636; RESULT-NEXT: %alloca = alloca [4096 x i32]637; RESULT-NEXT: store i32 12345678, ptr %arg638; RESULT-NEXT: store i32 0, ptr %alloca639; RESULT-NEXT: ret void640define void @callee_stacksize(ptr %arg) "inline-max-stacksize"="4" {641 %alloca = alloca [4096 x i32]642 store i32 12345678, ptr %arg643 store i32 0, ptr %alloca644 ret void645}646 647; CHECK-LABEL: define void @caller_stacksize(648; RESULT-NEXT: %alloca.i = alloca [4096 x i32], align 4649; RESULT-NEXT: call void @llvm.lifetime.start.p0(ptr %alloca.i)650; RESULT-NEXT: store i32 12345678, ptr %arg, align 4651; RESULT-NEXT: store i32 0, ptr %alloca.i, align 4652; RESULT-NEXT: call void @llvm.lifetime.end.p0(ptr %alloca.i)653; RESULT-NEXT: ret void654define void @caller_stacksize(ptr %arg) {655 call void @callee_stacksize(ptr %arg)656 ret void657}658 659; CHECK-LABEL: define void @callee_dynamic_alloca(660; RESULT-NEXT: %alloca = alloca i32, i32 %n, align 4661; RESULT-NEXT: store i32 12345678, ptr %arg, align 4662; RESULT-NEXT: store i32 0, ptr %alloca, align 4663; RESULT-NEXT: ret void664define void @callee_dynamic_alloca(ptr %arg, i32 %n) "inline-max-stacksize"="4" {665 %alloca = alloca i32, i32 %n666 store i32 12345678, ptr %arg667 store i32 0, ptr %alloca668 ret void669}670 671; CHECK-LABEL: define void @caller_dynamic_alloca(672; RESULT-NEXT: %savedstack = call ptr @llvm.stacksave.p0()673; RESULT-NEXT: %alloca.i = alloca i32, i32 %size, align 4674; RESULT-NEXT: store i32 12345678, ptr %arg, align 4675; RESULT-NEXT: store i32 0, ptr %alloca.i, align 4676; RESULT-NEXT: call void @llvm.stackrestore.p0(ptr %savedstack)677; RESULT-NEXT: ret void678define void @caller_dynamic_alloca(ptr %arg, i32 %size) {679 call void @callee_dynamic_alloca(ptr %arg, i32 %size)680 ret void681}682 683declare void @extern_noduplicate() noduplicate684 685; CHECK-LABEL: define void @callee_noduplicate_calls(686; RESULT-NEXT: call void @extern_noduplicate()687; RESULT-NEXT: call void @extern_noduplicate()688; RESULT-NEXT: ret void689define void @callee_noduplicate_calls() {690 call void @extern_noduplicate()691 call void @extern_noduplicate()692 ret void693}694 695; Ignore noduplicate restrictions696; CHECK-LABEL: define void @caller_noduplicate_calls_callee(697; RESULT-NEXT: call void @extern_noduplicate()698; RESULT-NEXT: call void @extern_noduplicate()699; RESULT-NEXT: call void @extern_noduplicate()700; RESULT-NEXT: call void @extern_noduplicate()701; RESULT-NEXT: ret void702define void @caller_noduplicate_calls_callee() {703 call void @callee_noduplicate_calls()704 call void @callee_noduplicate_calls()705 ret void706}707 708; CHECK-LABEL: define void @sanitize_address_callee(709; RESULT-NEXT: store i32 333, ptr %arg710; RESULT-NEXT: ret void711define void @sanitize_address_callee(ptr %arg) sanitize_address {712 store i32 333, ptr %arg713 ret void714}715 716; CHECK-LABEL: define void @no_sanitize_address_caller(717; RESULT-NEXT: store i32 333, ptr %arg718; RESULT-NEXT: ret void719define void @no_sanitize_address_caller(ptr %arg) {720 call void @sanitize_address_callee(ptr %arg)721 ret void722}723 724; CHECK-LABEL: define float @nonstrictfp_callee(725; RESULT-NEXT: %add = fadd float %a, %a726; RESULT-NEXT: ret float %add727define float @nonstrictfp_callee(float %a) {728 %add = fadd float %a, %a729 ret float %add730}731 732; CHECK-LABEL: define float @strictfp_caller(733; RESULT-NEXT: call float @llvm.experimental.constrained.fadd.f32(734; RESULT-NEXT: call float @llvm.experimental.constrained.fadd.f32(735; RESULT-NEXT: ret float %add736define float @strictfp_caller(float %a) strictfp {737 %call = call float @nonstrictfp_callee(float %a) strictfp738 %add = call float @llvm.experimental.constrained.fadd.f32(float %call, float 2.0, metadata !"round.dynamic", metadata !"fpexcept.strict")739 ret float %add740}741 742; CHECK-LABEL: define float @strictfp_callee(743; RESULT-NEXT: call float @llvm.experimental.constrained.fadd.f32(744; RESULT-NEXT: ret float745define float @strictfp_callee(float %a) strictfp {746 %add = call float @llvm.experimental.constrained.fadd.f32(float %a, float %a, metadata !"round.dynamic", metadata !"fpexcept.strict")747 ret float %add748}749 750; FIXME: This should not inline. The inlined case should fail the751; verifier, but it does not.752; CHECK-LABEL: define float @nonstrictfp_caller(753; RESULT-NEXT: call float @llvm.experimental.constrained.fadd.f32(754; RESULT-NEXT: fadd float755; RESULT-NEXT: ret float756define float @nonstrictfp_caller(float %a) {757 %call = call float @strictfp_callee(float %a)758 %add1 = fadd float %call, 2.0759 ret float %add1760}761 762define void @caller_also_has_non_callee_use() {763 call void @simple_callee(ptr @simple_callee)764 ret void765}766