Skip to content

Commit 4636011

Browse files
committed
Treat a musttail sibcall like a sibcall
In particular, we don't need to bother with shuffling arguments around on the stack, because in the x86 backend, only functions that do not need to move arguments around on the stack are considered sibcalls.
1 parent 83ec93f commit 4636011

File tree

4 files changed

+102
-30
lines changed

4 files changed

+102
-30
lines changed

llvm/lib/Target/X86/X86ISelLoweringCall.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2153,15 +2153,18 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
21532153
isTailCall = false;
21542154
}
21552155

2156-
if (isTailCall && !IsMustTail) {
2156+
if (isTailCall) {
21572157
// Check if it's really possible to do a tail call.
2158-
isTailCall = IsEligibleForTailCallOptimization(CLI, CCInfo, ArgLocs,
2159-
IsCalleePopSRet);
2158+
IsSibcall = IsEligibleForTailCallOptimization(CLI, CCInfo, ArgLocs,
2159+
IsCalleePopSRet);
2160+
2161+
if (!IsMustTail) {
2162+
isTailCall = IsSibcall;
21602163

2161-
// Sibcalls are automatically detected tailcalls which do not require
2162-
// ABI changes.
2163-
if (!IsGuaranteeTCO && isTailCall)
2164-
IsSibcall = true;
2164+
// Sibcalls are automatically detected tailcalls which do not require
2165+
// ABI changes.
2166+
IsSibcall = IsSibcall && !IsGuaranteeTCO;
2167+
}
21652168

21662169
if (isTailCall)
21672170
++NumTailCalls;
@@ -2183,8 +2186,9 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
21832186
else if (IsGuaranteeTCO && canGuaranteeTCO(CallConv))
21842187
NumBytes = GetAlignedArgumentStackSize(NumBytes, DAG);
21852188

2189+
// A sibcall is ABI-compatible and does not need to adjust the stack pointer.
21862190
int FPDiff = 0;
2187-
if (isTailCall &&
2191+
if (isTailCall && !IsSibcall &&
21882192
shouldGuaranteeTCO(CallConv,
21892193
MF.getTarget().Options.GuaranteedTailCallOpt)) {
21902194
// Lower arguments at fp - stackoffset + fpdiff.
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -x86-asm-syntax=intel | FileCheck %s
3+
; ; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s
4+
5+
; Test correct handling of a musttail call with a byval struct argument.
6+
7+
%struct.1xi32 = type { [1 x i32] }
8+
%struct.3xi32 = type { [3 x i32] }
9+
%struct.5xi32 = type { [5 x i32] }
10+
11+
declare dso_local i32 @Func1(ptr byval(%struct.1xi32) %0)
12+
declare dso_local i32 @Func3(ptr byval(%struct.3xi32) %0)
13+
declare dso_local i32 @Func5(ptr byval(%struct.5xi32) %0)
14+
declare dso_local i32 @FuncManyArgs(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i8 %6, ptr byval(%struct.5xi32) %7)
15+
16+
define dso_local i32 @test1(ptr byval(%struct.1xi32) %0) {
17+
; CHECK-LABEL: test1:
18+
; CHECK: # %bb.0:
19+
; CHECK-NEXT: jmp Func1 # TAILCALL
20+
%r = musttail call i32 @Func1(ptr byval(%struct.1xi32) %0)
21+
ret i32 %r
22+
}
23+
24+
define dso_local i32 @test3(ptr byval(%struct.3xi32) %0) {
25+
; CHECK-LABEL: test3:
26+
; CHECK: # %bb.0:
27+
; CHECK-NEXT: jmp Func3 # TAILCALL
28+
%r = musttail call i32 @Func3(ptr byval(%struct.3xi32) %0)
29+
ret i32 %r
30+
}
31+
32+
; sizeof(%struct.5xi32) > 16, in x64 this is passed on stack.
33+
define dso_local i32 @test5(ptr byval(%struct.5xi32) %0) {
34+
; CHECK-LABEL: test5:
35+
; CHECK: # %bb.0:
36+
; CHECK-NEXT: jmp Func5 # TAILCALL
37+
%r = musttail call i32 @Func5(ptr byval(%struct.5xi32) %0)
38+
ret i32 %r
39+
}
40+
41+
; Test passing multiple arguments with different sizes on stack. In x64 Linux
42+
; the first 6 are passed by register.
43+
define dso_local i32 @testManyArgs(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i8 %6, ptr byval(%struct.5xi32) %7) {
44+
; CHECK-LABEL: testManyArgs:
45+
; CHECK: # %bb.0:
46+
; CHECK-NEXT: jmp FuncManyArgs # TAILCALL
47+
%r = musttail call i32 @FuncManyArgs(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i8 %6, ptr byval(%struct.5xi32) %7)
48+
ret i32 %r
49+
}
50+
51+
define dso_local i32 @testRecursion(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i8 %6, ptr byval(%struct.5xi32) %7) {
52+
; CHECK-LABEL: testRecursion:
53+
; CHECK: # %bb.0:
54+
; CHECK-NEXT: jmp testRecursion # TAILCALL
55+
%r = musttail call i32 @testRecursion(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i8 %6, ptr byval(%struct.5xi32) %7)
56+
ret i32 %r
57+
}
58+
59+
define dso_local i32 @swap(ptr byval(%struct.1xi32) %0, ptr byval(%struct.1xi32) %1) noinline {
60+
; CHECK-LABEL: swap:
61+
; CHECK: # %bb.0: # %entry
62+
; CHECK-NEXT: mov eax, dword ptr [rsp + 8]
63+
; CHECK-NEXT: add eax, dword ptr [rsp + 16]
64+
; CHECK-NEXT: ret
65+
entry:
66+
%a.ptr = getelementptr inbounds %struct.1xi32, ptr %0, i32 0, i32 0, i32 0
67+
%a = load i32, ptr %a.ptr, align 4
68+
%b.ptr = getelementptr inbounds %struct.1xi32, ptr %1, i32 0, i32 0, i32 0
69+
%b = load i32, ptr %b.ptr, align 4
70+
%sum = add i32 %a, %b
71+
ret i32 %sum
72+
}
73+
74+
define dso_local i32 @swapByValArguments(ptr byval(%struct.1xi32) %0, ptr byval(%struct.1xi32) %1) {
75+
; CHECK-LABEL: swapArguments:
76+
; CHECK: # %bb.0:
77+
78+
; CHECK-NEXT: mov eax, dword ptr [rsp + 8]
79+
; CHECK-NEXT: mov dword ptr [rsp - 16], eax
80+
; CHECK-NEXT: mov ecx, dword ptr [rsp + 16]
81+
; CHECK-NEXT: mov dword ptr [rsp - 8], ecx
82+
83+
; CHECK-NEXT: mov dword ptr [rsp + 8], ecx
84+
; CHECK-NEXT: mov dword ptr [rsp + 16], eax
85+
; CHECK-NEXT: jmp swap # TAILCALL
86+
%r = musttail call i32 @swap(ptr byval(%struct.1xi32) %1, ptr byval(%struct.1xi32) %0)
87+
ret i32 %r
88+
}

llvm/test/CodeGen/X86/musttail-tailcc.ll

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,6 @@ define dso_local tailcc void @void_test(i32, i32, i32, i32) {
5555
;
5656
; X86-LABEL: void_test:
5757
; X86: # %bb.0: # %entry
58-
; X86-NEXT: pushl %esi
59-
; X86-NEXT: .cfi_def_cfa_offset 8
60-
; X86-NEXT: .cfi_offset %esi, -8
61-
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
62-
; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
63-
; X86-NEXT: movl %esi, {{[0-9]+}}(%esp)
64-
; X86-NEXT: movl %eax, {{[0-9]+}}(%esp)
65-
; X86-NEXT: popl %esi
66-
; X86-NEXT: .cfi_def_cfa_offset 4
6758
; X86-NEXT: jmp void_test # TAILCALL
6859
entry:
6960
musttail call tailcc void @void_test( i32 %0, i32 %1, i32 %2, i32 %3)
@@ -77,15 +68,6 @@ define dso_local tailcc i1 @i1test(i32, i32, i32, i32) {
7768
;
7869
; X86-LABEL: i1test:
7970
; X86: # %bb.0: # %entry
80-
; X86-NEXT: pushl %esi
81-
; X86-NEXT: .cfi_def_cfa_offset 8
82-
; X86-NEXT: .cfi_offset %esi, -8
83-
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
84-
; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
85-
; X86-NEXT: movl %esi, {{[0-9]+}}(%esp)
86-
; X86-NEXT: movl %eax, {{[0-9]+}}(%esp)
87-
; X86-NEXT: popl %esi
88-
; X86-NEXT: .cfi_def_cfa_offset 4
8971
; X86-NEXT: jmp i1test # TAILCALL
9072
entry:
9173
%4 = musttail call tailcc i1 @i1test( i32 %0, i32 %1, i32 %2, i32 %3)

llvm/test/CodeGen/X86/swifttailcc-store-ret-address-aliasing-stack-slot.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
12
; RUN: llc %s -o - | FileCheck %s
23

34
target triple = "x86_64-apple-macosx"
@@ -24,17 +25,14 @@ define swifttailcc void @test(ptr %0, ptr swiftasync %1, i64 %2, i64 %3, ptr %4,
2425
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r15
2526
; CHECK-NEXT: callq _foo
2627
; CHECK-NEXT: movq %r14, (%rax)
27-
; CHECK-NEXT: movl [[OFF:[0-9]+]](%rsp), %edx
28-
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rcx
29-
; CHECK-NEXT: movq %rcx, [[OFF]](%rsp)
28+
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %edx
3029
; CHECK-NEXT: movq %rax, %r14
3130
; CHECK-NEXT: movq %r13, %rdi
3231
; CHECK-NEXT: movq %r15, %rsi
3332
; CHECK-NEXT: movq %rbx, %r13
3433
; CHECK-NEXT: addq $8, %rsp
3534
; CHECK-NEXT: popq %rbx
3635
; CHECK-NEXT: popq %r15
37-
; CHECK-NEXT: addq $16, %rsp
3836
; CHECK-NEXT: jmp _tc_fn ## TAILCALL
3937
entry:
4038
%res = tail call ptr @foo()

0 commit comments

Comments
 (0)