202 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s -check-prefix=X643; RUN: llc < %s -mtriple=x86_64-windows-msvc | FileCheck %s -check-prefix=UEFI644; RUN: llc < %s -mtriple=x86_64-uefi | FileCheck %s -check-prefix=UEFI645; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s -check-prefix=X866 7; With -tailcallopt, CodeGen guarantees a tail call optimization8; for all of these.9 10declare dso_local tailcc i32 @tailcallee(i32 %a1, i32 %a2, i32 %a3, i32 %a4)11 12define dso_local tailcc i32 @tailcaller(i32 %in1, i32 %in2) nounwind {13; X64-LABEL: tailcaller:14; X64: # %bb.0: # %entry15; X64-NEXT: pushq %rax16; X64-NEXT: movl %edi, %edx17; X64-NEXT: movl %esi, %ecx18; X64-NEXT: popq %rax19; X64-NEXT: jmp tailcallee # TAILCALL20;21; UEFI64-LABEL: tailcaller:22; UEFI64: # %bb.0: # %entry23; UEFI64-NEXT: subq $40, %rsp24; UEFI64-NEXT: movl %ecx, %r8d25; UEFI64-NEXT: movl %edx, %r9d26; UEFI64-NEXT: addq $40, %rsp27; UEFI64-NEXT: jmp tailcallee # TAILCALL28;29; X86-LABEL: tailcaller:30; X86: # %bb.0: # %entry31; X86-NEXT: subl $16, %esp32; X86-NEXT: movl %ecx, {{[0-9]+}}(%esp)33; X86-NEXT: movl {{[0-9]+}}(%esp), %eax34; X86-NEXT: movl %edx, {{[0-9]+}}(%esp)35; X86-NEXT: movl %eax, {{[0-9]+}}(%esp)36; X86-NEXT: addl $8, %esp37; X86-NEXT: jmp tailcallee # TAILCALL38entry:39 %tmp11 = tail call tailcc i32 @tailcallee(i32 %in1, i32 %in2, i32 %in1, i32 %in2)40 ret i32 %tmp1141}42 43declare dso_local tailcc ptr @alias_callee()44 45define tailcc noalias ptr @noalias_caller() nounwind {46; X64-LABEL: noalias_caller:47; X64: # %bb.0:48; X64-NEXT: pushq %rax49; X64-NEXT: popq %rax50; X64-NEXT: jmp alias_callee # TAILCALL51;52; UEFI64-LABEL: noalias_caller:53; UEFI64: # %bb.0:54; UEFI64-NEXT: jmp alias_callee # TAILCALL55;56; X86-LABEL: noalias_caller:57; X86: # %bb.0:58; X86-NEXT: jmp alias_callee # TAILCALL59 %p = tail call tailcc ptr @alias_callee()60 ret ptr %p61}62 63declare dso_local tailcc noalias ptr @noalias_callee()64 65define dso_local tailcc ptr @alias_caller() nounwind {66; X64-LABEL: alias_caller:67; X64: # %bb.0:68; X64-NEXT: pushq %rax69; X64-NEXT: popq %rax70; X64-NEXT: jmp noalias_callee # TAILCALL71;72; UEFI64-LABEL: alias_caller:73; UEFI64: # %bb.0:74; UEFI64-NEXT: jmp noalias_callee # TAILCALL75;76; X86-LABEL: alias_caller:77; X86: # %bb.0:78; X86-NEXT: jmp noalias_callee # TAILCALL79 %p = tail call tailcc noalias ptr @noalias_callee()80 ret ptr %p81}82 83declare dso_local tailcc i32 @i32_callee()84 85define dso_local tailcc i32 @ret_undef() nounwind {86; X64-LABEL: ret_undef:87; X64: # %bb.0:88; X64-NEXT: pushq %rax89; X64-NEXT: popq %rax90; X64-NEXT: jmp i32_callee # TAILCALL91;92; UEFI64-LABEL: ret_undef:93; UEFI64: # %bb.0:94; UEFI64-NEXT: jmp i32_callee # TAILCALL95;96; X86-LABEL: ret_undef:97; X86: # %bb.0:98; X86-NEXT: jmp i32_callee # TAILCALL99 %p = tail call tailcc i32 @i32_callee()100 ret i32 undef101}102 103declare dso_local tailcc void @does_not_return()104 105define dso_local tailcc i32 @noret() nounwind {106; X64-LABEL: noret:107; X64: # %bb.0:108; X64-NEXT: pushq %rax109; X64-NEXT: popq %rax110; X64-NEXT: jmp does_not_return # TAILCALL111;112; UEFI64-LABEL: noret:113; UEFI64: # %bb.0:114; UEFI64-NEXT: jmp does_not_return # TAILCALL115;116; X86-LABEL: noret:117; X86: # %bb.0:118; X86-NEXT: jmp does_not_return # TAILCALL119 tail call tailcc void @does_not_return()120 unreachable121}122 123define dso_local tailcc void @void_test(i32, i32, i32, i32) {124; X64-LABEL: void_test:125; X64: # %bb.0: # %entry126; X64-NEXT: pushq %rax127; X64-NEXT: .cfi_def_cfa_offset 16128; X64-NEXT: popq %rax129; X64-NEXT: .cfi_def_cfa_offset 8130; X64-NEXT: jmp void_test # TAILCALL131;132; UEFI64-LABEL: void_test:133; UEFI64: # %bb.0: # %entry134; UEFI64-NEXT: subq $40, %rsp135; UEFI64-NEXT: .seh_stackalloc 40136; UEFI64-NEXT: .seh_endprologue137; UEFI64-NEXT: .seh_startepilogue138; UEFI64-NEXT: addq $40, %rsp139; UEFI64-NEXT: .seh_endepilogue140; UEFI64-NEXT: jmp void_test # TAILCALL141;142; X86-LABEL: void_test:143; X86: # %bb.0: # %entry144; X86-NEXT: pushl %esi145; X86-NEXT: .cfi_def_cfa_offset 8146; X86-NEXT: subl $8, %esp147; X86-NEXT: .cfi_def_cfa_offset 16148; X86-NEXT: .cfi_offset %esi, -8149; X86-NEXT: movl {{[0-9]+}}(%esp), %eax150; X86-NEXT: movl {{[0-9]+}}(%esp), %esi151; X86-NEXT: movl %esi, {{[0-9]+}}(%esp)152; X86-NEXT: movl %eax, {{[0-9]+}}(%esp)153; X86-NEXT: addl $8, %esp154; X86-NEXT: .cfi_def_cfa_offset 8155; X86-NEXT: popl %esi156; X86-NEXT: .cfi_def_cfa_offset 4157; X86-NEXT: jmp void_test # TAILCALL158 entry:159 tail call tailcc void @void_test( i32 %0, i32 %1, i32 %2, i32 %3)160 ret void161}162 163define dso_local tailcc i1 @i1test(i32, i32, i32, i32) {164; X64-LABEL: i1test:165; X64: # %bb.0: # %entry166; X64-NEXT: pushq %rax167; X64-NEXT: .cfi_def_cfa_offset 16168; X64-NEXT: popq %rax169; X64-NEXT: .cfi_def_cfa_offset 8170; X64-NEXT: jmp i1test # TAILCALL171;172; UEFI64-LABEL: i1test:173; UEFI64: # %bb.0: # %entry174; UEFI64-NEXT: subq $40, %rsp175; UEFI64-NEXT: .seh_stackalloc 40176; UEFI64-NEXT: .seh_endprologue177; UEFI64-NEXT: .seh_startepilogue178; UEFI64-NEXT: addq $40, %rsp179; UEFI64-NEXT: .seh_endepilogue180; UEFI64-NEXT: jmp i1test # TAILCALL181;182; X86-LABEL: i1test:183; X86: # %bb.0: # %entry184; X86-NEXT: pushl %esi185; X86-NEXT: .cfi_def_cfa_offset 8186; X86-NEXT: subl $8, %esp187; X86-NEXT: .cfi_def_cfa_offset 16188; X86-NEXT: .cfi_offset %esi, -8189; X86-NEXT: movl {{[0-9]+}}(%esp), %eax190; X86-NEXT: movl {{[0-9]+}}(%esp), %esi191; X86-NEXT: movl %esi, {{[0-9]+}}(%esp)192; X86-NEXT: movl %eax, {{[0-9]+}}(%esp)193; X86-NEXT: addl $8, %esp194; X86-NEXT: .cfi_def_cfa_offset 8195; X86-NEXT: popl %esi196; X86-NEXT: .cfi_def_cfa_offset 4197; X86-NEXT: jmp i1test # TAILCALL198 entry:199 %4 = tail call tailcc i1 @i1test( i32 %0, i32 %1, i32 %2, i32 %3)200 ret i1 %4201}202