brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.0 KiB · b2bf3bb Raw
240 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt < %s -passes=inline -S | FileCheck %s3 4; We have to apply the less restrictive TailCallKind of the call site being5; inlined and any call sites cloned into the caller.6 7; No tail marker after inlining, since test_capture_c captures an alloca.8declare void @test_capture_c(ptr)9define internal void @test_capture_b(ptr %P) {10  tail call void @test_capture_c(ptr %P)11  ret void12}13define void @test_capture_a() {14; CHECK-LABEL: define void @test_capture_a() {15; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 416; CHECK-NEXT:    call void @test_capture_c(ptr [[A]])17; CHECK-NEXT:    ret void18;19  %A = alloca i32  		; captured by test_capture_b20  call void @test_capture_b(ptr %A)21  ret void22}23 24; No musttail marker after inlining, since the prototypes don't match.25declare void @test_proto_mismatch_c(ptr)26define internal void @test_proto_mismatch_b(ptr %p) {27  musttail call void @test_proto_mismatch_c(ptr %p)28  ret void29}30define void @test_proto_mismatch_a() {31; CHECK-LABEL: define void @test_proto_mismatch_a() {32; CHECK-NEXT:    call void @test_proto_mismatch_c(ptr null)33; CHECK-NEXT:    ret void34;35  call void @test_proto_mismatch_b(ptr null)36  ret void37}38 39; After inlining through a musttail call site, we need to keep musttail markers40; to prevent unbounded stack growth.41declare void @test_musttail_basic_c(ptr %p)42define internal void @test_musttail_basic_b(ptr %p) {43  musttail call void @test_musttail_basic_c(ptr %p)44  ret void45}46define void @test_musttail_basic_a(ptr %p) {47; CHECK-LABEL: define void @test_musttail_basic_a48; CHECK-SAME: (ptr [[P:%.*]]) {49; CHECK-NEXT:    musttail call void @test_musttail_basic_c(ptr [[P]])50; CHECK-NEXT:    ret void51;52  musttail call void @test_musttail_basic_b(ptr %p)53  ret void54}55 56; Don't insert lifetime end markers here, the lifetime is trivially over due57; the return.58declare void @test_byval_c(ptr byval(i32) %p)59define internal void @test_byval_b(ptr byval(i32) %p) {60  musttail call void @test_byval_c(ptr byval(i32) %p)61  ret void62}63define void @test_byval_a(ptr byval(i32) %p) {64; CHECK-LABEL: define void @test_byval_a65; CHECK-SAME: (ptr byval(i32) [[P:%.*]]) {66; CHECK-NEXT:    [[P1:%.*]] = alloca i32, align 467; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[P1]])68; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[P1]], ptr [[P]], i64 4, i1 false)69; CHECK-NEXT:    musttail call void @test_byval_c(ptr byval(i32) [[P1]])70; CHECK-NEXT:    ret void71;72  musttail call void @test_byval_b(ptr byval(i32) %p)73  ret void74}75 76; Don't insert a stack restore, we're about to return.77declare void @escape(ptr %buf)78declare void @test_dynalloca_c(ptr byval(i32) %p, i32 %n)79define internal void @test_dynalloca_b(ptr byval(i32) %p, i32 %n) alwaysinline {80  %buf = alloca i8, i32 %n              ; dynamic alloca81  call void @escape(ptr %buf)           ; escape it82  musttail call void @test_dynalloca_c(ptr byval(i32) %p, i32 %n)83  ret void84}85define void @test_dynalloca_a(ptr byval(i32) %p, i32 %n) {86; CHECK-LABEL: define void @test_dynalloca_a87; CHECK-SAME: (ptr byval(i32) [[P:%.*]], i32 [[N:%.*]]) {88; CHECK-NEXT:    [[P1:%.*]] = alloca i32, align 489; CHECK-NEXT:    [[SAVEDSTACK:%.*]] = call ptr @llvm.stacksave.p0()90; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[P1]])91; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[P1]], ptr [[P]], i64 4, i1 false)92; CHECK-NEXT:    [[BUF_I:%.*]] = alloca i8, i32 [[N]], align 193; CHECK-NEXT:    call void @escape(ptr [[BUF_I]])94; CHECK-NEXT:    musttail call void @test_dynalloca_c(ptr byval(i32) [[P1]], i32 [[N]])95; CHECK-NEXT:    ret void96;97  musttail call void @test_dynalloca_b(ptr byval(i32) %p, i32 %n)98  ret void99}100 101; We can't merge the returns.102declare void @test_multiret_c(i1 zeroext %b)103declare void @test_multiret_d(i1 zeroext %b)104define internal void @test_multiret_b(i1 zeroext %b) {105  br i1 %b, label %c, label %d106c:107  musttail call void @test_multiret_c(i1 zeroext %b)108  ret void109d:110  musttail call void @test_multiret_d(i1 zeroext %b)111  ret void112}113define void @test_multiret_a(i1 zeroext %b) {114; CHECK-LABEL: define void @test_multiret_a115; CHECK-SAME: (i1 zeroext [[B:%.*]]) {116; CHECK-NEXT:    br i1 [[B]], label [[C_I:%.*]], label [[D_I:%.*]]117; CHECK:       c.i:118; CHECK-NEXT:    musttail call void @test_multiret_c(i1 zeroext [[B]])119; CHECK-NEXT:    ret void120; CHECK:       d.i:121; CHECK-NEXT:    musttail call void @test_multiret_d(i1 zeroext [[B]])122; CHECK-NEXT:    ret void123;124  musttail call void @test_multiret_b(i1 zeroext %b)125  ret void126}127 128; We have to avoid bitcast chains.129declare ptr @test_retptr_c()130define internal ptr @test_retptr_b() {131  %rv = musttail call ptr @test_retptr_c()132  ret ptr %rv133}134define ptr @test_retptr_a() {135; CHECK-LABEL: define ptr @test_retptr_a() {136; CHECK-NEXT:    [[RV_I:%.*]] = musttail call ptr @test_retptr_c()137; CHECK-NEXT:    ret ptr [[RV_I]]138;139  %rv = musttail call ptr @test_retptr_b()140  ret ptr %rv141}142 143; Combine the last two cases: multiple returns with pointer bitcasts.144declare ptr @test_multiptrret_c(i1 zeroext %b)145declare ptr @test_multiptrret_d(i1 zeroext %b)146define internal ptr @test_multiptrret_b(i1 zeroext %b) {147  br i1 %b, label %c, label %d148c:149  %c_rv = musttail call ptr @test_multiptrret_c(i1 zeroext %b)150  ret ptr %c_rv151d:152  %d_rv = musttail call ptr @test_multiptrret_d(i1 zeroext %b)153  ret ptr %d_rv154}155define ptr @test_multiptrret_a(i1 zeroext %b) {156; CHECK-LABEL: define ptr @test_multiptrret_a157; CHECK-SAME: (i1 zeroext [[B:%.*]]) {158; CHECK-NEXT:    br i1 [[B]], label [[C_I:%.*]], label [[D_I:%.*]]159; CHECK:       c.i:160; CHECK-NEXT:    [[C_RV_I:%.*]] = musttail call ptr @test_multiptrret_c(i1 zeroext [[B]])161; CHECK-NEXT:    ret ptr [[C_RV_I]]162; CHECK:       d.i:163; CHECK-NEXT:    [[D_RV_I:%.*]] = musttail call ptr @test_multiptrret_d(i1 zeroext [[B]])164; CHECK-NEXT:    ret ptr [[D_RV_I]]165;166  %rv = musttail call ptr @test_multiptrret_b(i1 zeroext %b)167  ret ptr %rv168}169 170; Inline a musttail call site which contains a normal return and a musttail call.171declare i32 @test_mixedret_c(i1 zeroext %b)172declare i32 @test_mixedret_d(i1 zeroext %b)173define internal i32 @test_mixedret_b(i1 zeroext %b) {174  br i1 %b, label %c, label %d175c:176  %c_rv = musttail call i32 @test_mixedret_c(i1 zeroext %b)177  ret i32 %c_rv178d:179  %d_rv = call i32 @test_mixedret_d(i1 zeroext %b)180  %d_rv1 = add i32 1, %d_rv181  ret i32 %d_rv1182}183define i32 @test_mixedret_a(i1 zeroext %b) {184; CHECK-LABEL: define i32 @test_mixedret_a185; CHECK-SAME: (i1 zeroext [[B:%.*]]) {186; CHECK-NEXT:    br i1 [[B]], label [[C_I:%.*]], label [[TEST_MIXEDRET_B_EXIT:%.*]]187; CHECK:       c.i:188; CHECK-NEXT:    [[C_RV_I:%.*]] = musttail call i32 @test_mixedret_c(i1 zeroext [[B]])189; CHECK-NEXT:    ret i32 [[C_RV_I]]190; CHECK:       test_mixedret_b.exit:191; CHECK-NEXT:    [[D_RV_I:%.*]] = call i32 @test_mixedret_d(i1 zeroext [[B]])192; CHECK-NEXT:    [[D_RV1_I:%.*]] = add i32 1, [[D_RV_I]]193; CHECK-NEXT:    ret i32 [[D_RV1_I]]194;195  %rv = musttail call i32 @test_mixedret_b(i1 zeroext %b)196  ret i32 %rv197}198 199declare i32 @donttailcall()200 201define i32 @notail() {202; CHECK-LABEL: define i32 @notail() {203; CHECK-NEXT:    [[RV:%.*]] = notail call i32 @donttailcall()204; CHECK-NEXT:    ret i32 [[RV]]205;206  %rv = notail call i32 @donttailcall()207  ret i32 %rv208}209 210define i32 @test_notail() {211; CHECK-LABEL: define i32 @test_notail() {212; CHECK-NEXT:    [[RV_I:%.*]] = notail call i32 @donttailcall()213; CHECK-NEXT:    ret i32 [[RV_I]]214;215  %rv = tail call i32 @notail()216  ret i32 %rv217}218 219; PR31014: Inlining a musttail call through a notail call site should remove220; any tail marking, otherwise we break verifier invariants.221 222declare void @do_ret(i32)223 224define void @test_notail_inline_musttail(i32 %a) {225; CHECK-LABEL: define void @test_notail_inline_musttail226; CHECK-SAME: (i32 [[A:%.*]]) {227; CHECK-NEXT:    call void @do_ret(i32 [[A]])228; CHECK-NEXT:    musttail call void @do_ret(i32 [[A]])229; CHECK-NEXT:    ret void230;231  notail call void @inline_musttail(i32 %a)232  musttail call void @do_ret(i32 %a)233  ret void234}235 236define internal void @inline_musttail(i32 %a) {237  musttail call void @do_ret(i32 %a)238  ret void239}240