Skip to content

[llvm] Allow Fast and Tail CC in UEFI #138361

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion llvm/lib/Target/X86/X86Subtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -352,9 +352,9 @@ class X86Subtarget final : public X86GenSubtargetInfo {
switch (CC) {
// On Win64, all these conventions just use the default convention.
case CallingConv::C:
return isTargetWin64() || isTargetUEFI64();
case CallingConv::Fast:
case CallingConv::Tail:
return isTargetWin64() || isTargetUEFI64();
case CallingConv::Swift:
case CallingConv::SwiftTail:
case CallingConv::X86_FastCall:
Expand Down
1 change: 1 addition & 0 deletions llvm/test/CodeGen/X86/musttail-tailcc.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s -check-prefix=X64
; RUN: llc < %s -mtriple=x86_64-uefi | FileCheck %s -check-prefix=X64
; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s -check-prefix=X32

; tailcc will turn all of these musttail calls into tail calls.
Expand Down
46 changes: 46 additions & 0 deletions llvm/test/CodeGen/X86/tailcall-tailcc.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s -check-prefix=X64
; RUN: llc < %s -mtriple=x86_64-windows-msvc | FileCheck %s -check-prefix=UEFI64
; RUN: llc < %s -mtriple=x86_64-uefi | FileCheck %s -check-prefix=UEFI64
; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s -check-prefix=X32

; With -tailcallopt, CodeGen guarantees a tail call optimization
Expand All @@ -16,6 +18,14 @@ define dso_local tailcc i32 @tailcaller(i32 %in1, i32 %in2) nounwind {
; X64-NEXT: popq %rax
; X64-NEXT: jmp tailcallee # TAILCALL
;
; UEFI64-LABEL: tailcaller:
; UEFI64: # %bb.0: # %entry
; UEFI64-NEXT: subq $40, %rsp
; UEFI64-NEXT: movl %ecx, %r8d
; UEFI64-NEXT: movl %edx, %r9d
; UEFI64-NEXT: addq $40, %rsp
; UEFI64-NEXT: jmp tailcallee # TAILCALL
;
; X32-LABEL: tailcaller:
; X32: # %bb.0: # %entry
; X32-NEXT: subl $16, %esp
Expand All @@ -39,6 +49,10 @@ define tailcc noalias ptr @noalias_caller() nounwind {
; X64-NEXT: popq %rax
; X64-NEXT: jmp alias_callee # TAILCALL
;
; UEFI64-LABEL: noalias_caller:
; UEFI64: # %bb.0:
; UEFI64-NEXT: jmp alias_callee # TAILCALL
;
; X32-LABEL: noalias_caller:
; X32: # %bb.0:
; X32-NEXT: jmp alias_callee # TAILCALL
Expand All @@ -55,6 +69,10 @@ define dso_local tailcc ptr @alias_caller() nounwind {
; X64-NEXT: popq %rax
; X64-NEXT: jmp noalias_callee # TAILCALL
;
; UEFI64-LABEL: alias_caller:
; UEFI64: # %bb.0:
; UEFI64-NEXT: jmp noalias_callee # TAILCALL
;
; X32-LABEL: alias_caller:
; X32: # %bb.0:
; X32-NEXT: jmp noalias_callee # TAILCALL
Expand All @@ -71,6 +89,10 @@ define dso_local tailcc i32 @ret_undef() nounwind {
; X64-NEXT: popq %rax
; X64-NEXT: jmp i32_callee # TAILCALL
;
; UEFI64-LABEL: ret_undef:
; UEFI64: # %bb.0:
; UEFI64-NEXT: jmp i32_callee # TAILCALL
;
; X32-LABEL: ret_undef:
; X32: # %bb.0:
; X32-NEXT: jmp i32_callee # TAILCALL
Expand All @@ -87,6 +109,10 @@ define dso_local tailcc i32 @noret() nounwind {
; X64-NEXT: popq %rax
; X64-NEXT: jmp does_not_return # TAILCALL
;
; UEFI64-LABEL: noret:
; UEFI64: # %bb.0:
; UEFI64-NEXT: jmp does_not_return # TAILCALL
;
; X32-LABEL: noret:
; X32: # %bb.0:
; X32-NEXT: jmp does_not_return # TAILCALL
Expand All @@ -103,6 +129,16 @@ define dso_local tailcc void @void_test(i32, i32, i32, i32) {
; X64-NEXT: .cfi_def_cfa_offset 8
; X64-NEXT: jmp void_test # TAILCALL
;
; UEFI64-LABEL: void_test:
; UEFI64: # %bb.0: # %entry
; UEFI64-NEXT: subq $40, %rsp
; UEFI64-NEXT: .seh_stackalloc 40
; UEFI64-NEXT: .seh_endprologue
; UEFI64-NEXT: .seh_startepilogue
; UEFI64-NEXT: addq $40, %rsp
; UEFI64-NEXT: .seh_endepilogue
; UEFI64-NEXT: jmp void_test # TAILCALL
;
; X32-LABEL: void_test:
; X32: # %bb.0: # %entry
; X32-NEXT: pushl %esi
Expand Down Expand Up @@ -133,6 +169,16 @@ define dso_local tailcc i1 @i1test(i32, i32, i32, i32) {
; X64-NEXT: .cfi_def_cfa_offset 8
; X64-NEXT: jmp i1test # TAILCALL
;
; UEFI64-LABEL: i1test:
; UEFI64: # %bb.0: # %entry
; UEFI64-NEXT: subq $40, %rsp
; UEFI64-NEXT: .seh_stackalloc 40
; UEFI64-NEXT: .seh_endprologue
; UEFI64-NEXT: .seh_startepilogue
; UEFI64-NEXT: addq $40, %rsp
; UEFI64-NEXT: .seh_endepilogue
; UEFI64-NEXT: jmp i1test # TAILCALL
;
; X32-LABEL: i1test:
; X32: # %bb.0: # %entry
; X32-NEXT: pushl %esi
Expand Down
17 changes: 17 additions & 0 deletions llvm/test/CodeGen/X86/tailcc-fastcc.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -tailcallopt < %s -mtriple=x86_64-unknown-unknown | FileCheck %s -check-prefix=X64
; RUN: llc -tailcallopt < %s -mtriple=x86_64-uefi | FileCheck %s -check-prefix=UEFI64
; RUN: llc -tailcallopt < %s -mtriple=i686-unknown-unknown | FileCheck %s -check-prefix=X32

; llc -tailcallopt should not enable tail calls from fastcc to tailcc or vice versa
Expand All @@ -15,6 +16,14 @@ define fastcc i32 @tailcaller1(i32 %in1, i32 %in2) nounwind {
; X64-NEXT: callq tailcallee1@PLT
; X64-NEXT: retq $8
;
; UEFI64-LABEL: tailcaller1:
; UEFI64: # %bb.0: # %entry
; UEFI64-NEXT: subq $40, %rsp
; UEFI64-NEXT: movl %ecx, %r8d
; UEFI64-NEXT: movl %edx, %r9d
; UEFI64-NEXT: callq tailcallee1
; UEFI64-NEXT: retq $40
;
; X32-LABEL: tailcaller1:
; X32: # %bb.0: # %entry
; X32-NEXT: pushl %edx
Expand All @@ -37,6 +46,14 @@ define tailcc i32 @tailcaller2(i32 %in1, i32 %in2) nounwind {
; X64-NEXT: callq tailcallee2@PLT
; X64-NEXT: retq $8
;
; UEFI64-LABEL: tailcaller2:
; UEFI64: # %bb.0: # %entry
; UEFI64-NEXT: subq $40, %rsp
; UEFI64-NEXT: movl %ecx, %r8d
; UEFI64-NEXT: movl %edx, %r9d
; UEFI64-NEXT: callq tailcallee2
; UEFI64-NEXT: retq $40
;
; X32-LABEL: tailcaller2:
; X32: # %bb.0: # %entry
; X32-NEXT: pushl %edx
Expand Down
6 changes: 4 additions & 2 deletions llvm/test/CodeGen/X86/tailcc-fastisel.ll
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
; RUN: llc < %s -mtriple=x86_64-apple-darwin -fast-isel -fast-isel-abort=1 | FileCheck %s
; RUN: llc < %s -mtriple=x86_64-apple-darwin -fast-isel -fast-isel-abort=1 | FileCheck %s -check-prefix=DARWIN64
; RUN: llc < %s -mtriple=x86_64-uefi -fast-isel -fast-isel-abort=1 | FileCheck %s -check-prefix=UEFI64

%0 = type { i64, i32, ptr }

define tailcc ptr @"visit_array_aux<`Reference>"(%0 %arg, i32 %arg1) nounwind {
fail: ; preds = %entry
%tmp20 = tail call tailcc ptr @"visit_array_aux<`Reference>"(%0 %arg, i32 undef) ; <ptr> [#uses=1]
; CHECK: jmp "_visit_array_aux<`Reference>" ## TAILCALL
; DARWIN64: jmp "_visit_array_aux<`Reference>" ## TAILCALL
; UEFI64: jmp "visit_array_aux<`Reference>" # TAILCALL
ret ptr %tmp20
}

Expand Down
1 change: 1 addition & 0 deletions llvm/test/CodeGen/X86/tailccstack64.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -post-RA-scheduler=true | FileCheck %s
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-win32 -post-RA-scheduler=true | FileCheck %s
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-uefi -post-RA-scheduler=true | FileCheck %s

; FIXME: Redundant unused stack allocation could be eliminated.
; CHECK: subq ${{24|72|80}}, %rsp
Expand Down
19 changes: 19 additions & 0 deletions llvm/test/CodeGen/X86/uefi-fastcc.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
; RUN: llc < %s -mtriple=x86_64-uefi | FileCheck %s -check-prefix=UEFIFAST64
; RUN: llc < %s -mtriple=x86_64-windows-msvc | FileCheck %s -check-prefix=UEFIFAST64

declare fastcc i32 @fastcallee1(i32 %a1, i32 %a2, i32 %a3, i32 %a4)

define fastcc i32 @fastcaller1(i32 %in1, i32 %in2) nounwind {
;; Test that the caller allocates stack space for callee to spill the register arguments.
; UEFIFAST64-LABEL: fastcaller1:
; UEFIFAST64: # %bb.0: # %entry
; UEFIFAST64-NEXT: subq $40, %rsp
; UEFIFAST64-NEXT: movl %ecx, %r8d
; UEFIFAST64-NEXT: movl %edx, %r9d
; UEFIFAST64-NEXT: callq fastcallee1
; UEFIFAST64-NEXT: addq $40, %rsp
; UEFIFAST64-NEXT: retq
entry:
%tmp11 = call fastcc i32 @fastcallee1(i32 %in1, i32 %in2, i32 %in1, i32 %in2)
ret i32 %tmp11
}