Stackmap shadows should consider call returns a branch target.
[oota-llvm.git] / test / CodeGen / X86 / musttail-varargs.ll
1 ; RUN: llc < %s -enable-tail-merge=0 -mtriple=x86_64-linux | FileCheck %s --check-prefix=LINUX
2 ; RUN: llc < %s -enable-tail-merge=0 -mtriple=x86_64-windows | FileCheck %s --check-prefix=WINDOWS
3
4 ; Test that we actually spill and reload all arguments in the variadic argument
5 ; pack. Doing a normal call will clobber all argument registers, and we will
6 ; spill around it. A simple adjustment should not require any XMM spills.
7
8 declare void(i8*, ...)* @get_f(i8* %this)
9
10 define void @f_thunk(i8* %this, ...) {
11   %fptr = call void(i8*, ...)*(i8*)* @get_f(i8* %this)
12   musttail call void (i8*, ...)* %fptr(i8* %this, ...)
13   ret void
14 }
15
16 ; Save and restore 6 GPRs, 8 XMMs, and AL around the call.
17
18 ; LINUX-LABEL: f_thunk:
19 ; LINUX-DAG: movq %rdi, {{.*}}
20 ; LINUX-DAG: movq %rsi, {{.*}}
21 ; LINUX-DAG: movq %rdx, {{.*}}
22 ; LINUX-DAG: movq %rcx, {{.*}}
23 ; LINUX-DAG: movq %r8, {{.*}}
24 ; LINUX-DAG: movq %r9, {{.*}}
25 ; LINUX-DAG: movb %al, {{.*}}
26 ; LINUX-DAG: movaps %xmm0, {{[0-9]*}}(%rsp)
27 ; LINUX-DAG: movaps %xmm1, {{[0-9]*}}(%rsp)
28 ; LINUX-DAG: movaps %xmm2, {{[0-9]*}}(%rsp)
29 ; LINUX-DAG: movaps %xmm3, {{[0-9]*}}(%rsp)
30 ; LINUX-DAG: movaps %xmm4, {{[0-9]*}}(%rsp)
31 ; LINUX-DAG: movaps %xmm5, {{[0-9]*}}(%rsp)
32 ; LINUX-DAG: movaps %xmm6, {{[0-9]*}}(%rsp)
33 ; LINUX-DAG: movaps %xmm7, {{[0-9]*}}(%rsp)
34 ; LINUX: callq get_f
35 ; LINUX-DAG: movaps {{[0-9]*}}(%rsp), %xmm0
36 ; LINUX-DAG: movaps {{[0-9]*}}(%rsp), %xmm1
37 ; LINUX-DAG: movaps {{[0-9]*}}(%rsp), %xmm2
38 ; LINUX-DAG: movaps {{[0-9]*}}(%rsp), %xmm3
39 ; LINUX-DAG: movaps {{[0-9]*}}(%rsp), %xmm4
40 ; LINUX-DAG: movaps {{[0-9]*}}(%rsp), %xmm5
41 ; LINUX-DAG: movaps {{[0-9]*}}(%rsp), %xmm6
42 ; LINUX-DAG: movaps {{[0-9]*}}(%rsp), %xmm7
43 ; LINUX-DAG: movq {{.*}}, %rdi
44 ; LINUX-DAG: movq {{.*}}, %rsi
45 ; LINUX-DAG: movq {{.*}}, %rdx
46 ; LINUX-DAG: movq {{.*}}, %rcx
47 ; LINUX-DAG: movq {{.*}}, %r8
48 ; LINUX-DAG: movq {{.*}}, %r9
49 ; LINUX-DAG: movb {{.*}}, %al
50 ; LINUX: jmpq *{{.*}}  # TAILCALL
51
52 ; WINDOWS-LABEL: f_thunk:
53 ; WINDOWS-NOT: mov{{.}}ps
54 ; WINDOWS-DAG: movq %rdx, {{.*}}
55 ; WINDOWS-DAG: movq %rcx, {{.*}}
56 ; WINDOWS-DAG: movq %r8, {{.*}}
57 ; WINDOWS-DAG: movq %r9, {{.*}}
58 ; WINDOWS-NOT: mov{{.}}ps
59 ; WINDOWS: callq get_f
60 ; WINDOWS-NOT: mov{{.}}ps
61 ; WINDOWS-DAG: movq {{.*}}, %rdx
62 ; WINDOWS-DAG: movq {{.*}}, %rcx
63 ; WINDOWS-DAG: movq {{.*}}, %r8
64 ; WINDOWS-DAG: movq {{.*}}, %r9
65 ; WINDOWS-NOT: mov{{.}}ps
66 ; WINDOWS: jmpq *{{.*}} # TAILCALL
67
68 ; This thunk shouldn't require any spills and reloads, assuming the register
69 ; allocator knows what it's doing.
70
71 define void @g_thunk(i8* %fptr_i8, ...) {
72   %fptr = bitcast i8* %fptr_i8 to void (i8*, ...)*
73   musttail call void (i8*, ...)* %fptr(i8* %fptr_i8, ...)
74   ret void
75 }
76
77 ; LINUX-LABEL: g_thunk:
78 ; LINUX-NOT: movq
79 ; LINUX: jmpq *%rdi  # TAILCALL
80
81 ; WINDOWS-LABEL: g_thunk:
82 ; WINDOWS-NOT: movq
83 ; WINDOWS: jmpq *%rcx # TAILCALL
84
85 ; Do a simple multi-exit multi-bb test.
86
87 %struct.Foo = type { i1, i8*, i8* }
88
89 @g = external global i32
90
91 define void @h_thunk(%struct.Foo* %this, ...) {
92   %cond_p = getelementptr %struct.Foo* %this, i32 0, i32 0
93   %cond = load i1* %cond_p
94   br i1 %cond, label %then, label %else
95
96 then:
97   %a_p = getelementptr %struct.Foo* %this, i32 0, i32 1
98   %a_i8 = load i8** %a_p
99   %a = bitcast i8* %a_i8 to void (%struct.Foo*, ...)*
100   musttail call void (%struct.Foo*, ...)* %a(%struct.Foo* %this, ...)
101   ret void
102
103 else:
104   %b_p = getelementptr %struct.Foo* %this, i32 0, i32 2
105   %b_i8 = load i8** %b_p
106   %b = bitcast i8* %b_i8 to void (%struct.Foo*, ...)*
107   store i32 42, i32* @g
108   musttail call void (%struct.Foo*, ...)* %b(%struct.Foo* %this, ...)
109   ret void
110 }
111
112 ; LINUX-LABEL: h_thunk:
113 ; LINUX: jne
114 ; LINUX: jmpq *{{.*}} # TAILCALL
115 ; LINUX: jmpq *{{.*}} # TAILCALL
116 ; WINDOWS-LABEL: h_thunk:
117 ; WINDOWS: jne
118 ; WINDOWS: jmpq *{{.*}} # TAILCALL
119 ; WINDOWS: jmpq *{{.*}} # TAILCALL