Skip to content

Commit 92b22b4

Browse files
committed
fix x86 musttail sibcalls
1 parent 2936852 commit 92b22b4

File tree

4 files changed

+71
-30
lines changed

4 files changed

+71
-30
lines changed

llvm/lib/Target/X86/X86ISelLoweringCall.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2098,15 +2098,18 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
20982098
isTailCall = false;
20992099
}
21002100

2101-
if (isTailCall && !IsMustTail) {
2101+
if (isTailCall) {
21022102
// Check if it's really possible to do a tail call.
2103-
isTailCall = IsEligibleForTailCallOptimization(CLI, CCInfo, ArgLocs,
2104-
IsCalleePopSRet);
2103+
IsSibcall = IsEligibleForTailCallOptimization(CLI, CCInfo, ArgLocs,
2104+
IsCalleePopSRet);
2105+
2106+
if (!IsMustTail) {
2107+
isTailCall = IsSibcall;
21052108

2106-
// Sibcalls are automatically detected tailcalls which do not require
2107-
// ABI changes.
2108-
if (!IsGuaranteeTCO && isTailCall)
2109-
IsSibcall = true;
2109+
// Sibcalls are automatically detected tailcalls which do not require
2110+
// ABI changes.
2111+
IsSibcall = IsSibcall && !IsGuaranteeTCO;
2112+
}
21102113

21112114
if (isTailCall)
21122115
++NumTailCalls;
@@ -2128,8 +2131,9 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
21282131
else if (IsGuaranteeTCO && canGuaranteeTCO(CallConv))
21292132
NumBytes = GetAlignedArgumentStackSize(NumBytes, DAG);
21302133

2134+
// A sibcall is ABI-compatible and does not need to adjust the stack pointer.
21312135
int FPDiff = 0;
2132-
if (isTailCall &&
2136+
if (isTailCall && !IsSibcall &&
21332137
shouldGuaranteeTCO(CallConv,
21342138
MF.getTarget().Options.GuaranteedTailCallOpt)) {
21352139
// Lower arguments at fp - stackoffset + fpdiff.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: llc < %s -mtriple=x86_64-unknown-unknown | 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+
}

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)