comparison test/CodeGen/X86/musttail-varargs.ll @ 95:afa8332a0e37 LLVM3.8

LLVM 3.8
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Tue, 13 Oct 2015 17:48:58 +0900
parents 60c9769439b8
children 7d135dc70f03
comparison
equal deleted inserted replaced
84:f3e34b893a5f 95:afa8332a0e37
1 ; RUN: llc < %s -enable-tail-merge=0 -mtriple=x86_64-linux | FileCheck %s --check-prefix=LINUX 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-linux-gnux32 | FileCheck %s --check-prefix=LINUX-X32
2 ; RUN: llc < %s -enable-tail-merge=0 -mtriple=x86_64-windows | FileCheck %s --check-prefix=WINDOWS 3 ; RUN: llc < %s -enable-tail-merge=0 -mtriple=x86_64-windows | FileCheck %s --check-prefix=WINDOWS
3 ; RUN: llc < %s -enable-tail-merge=0 -mtriple=i686-windows | FileCheck %s --check-prefix=X86 4 ; RUN: llc < %s -enable-tail-merge=0 -mtriple=i686-windows | FileCheck %s --check-prefix=X86
4 5
5 ; Test that we actually spill and reload all arguments in the variadic argument 6 ; Test that we actually spill and reload all arguments in the variadic argument
6 ; pack. Doing a normal call will clobber all argument registers, and we will 7 ; pack. Doing a normal call will clobber all argument registers, and we will
14 ; Use va_start so that we exercise the combination. 15 ; Use va_start so that we exercise the combination.
15 %ap = alloca [4 x i8*], align 16 16 %ap = alloca [4 x i8*], align 16
16 %ap_i8 = bitcast [4 x i8*]* %ap to i8* 17 %ap_i8 = bitcast [4 x i8*]* %ap to i8*
17 call void @llvm.va_start(i8* %ap_i8) 18 call void @llvm.va_start(i8* %ap_i8)
18 19
19 %fptr = call void(i8*, ...)*(i8*)* @get_f(i8* %this) 20 %fptr = call void(i8*, ...)*(i8*) @get_f(i8* %this)
20 musttail call void (i8*, ...)* %fptr(i8* %this, ...) 21 musttail call void (i8*, ...) %fptr(i8* %this, ...)
21 ret void 22 ret void
22 } 23 }
23 24
24 ; Save and restore 6 GPRs, 8 XMMs, and AL around the call. 25 ; Save and restore 6 GPRs, 8 XMMs, and AL around the call.
25 26
55 ; LINUX-DAG: movq {{.*}}, %r8 56 ; LINUX-DAG: movq {{.*}}, %r8
56 ; LINUX-DAG: movq {{.*}}, %r9 57 ; LINUX-DAG: movq {{.*}}, %r9
57 ; LINUX-DAG: movb {{.*}}, %al 58 ; LINUX-DAG: movb {{.*}}, %al
58 ; LINUX: jmpq *{{.*}} # TAILCALL 59 ; LINUX: jmpq *{{.*}} # TAILCALL
59 60
61 ; LINUX-X32-LABEL: f_thunk:
62 ; LINUX-X32-DAG: movl %edi, {{.*}}
63 ; LINUX-X32-DAG: movq %rsi, {{.*}}
64 ; LINUX-X32-DAG: movq %rdx, {{.*}}
65 ; LINUX-X32-DAG: movq %rcx, {{.*}}
66 ; LINUX-X32-DAG: movq %r8, {{.*}}
67 ; LINUX-X32-DAG: movq %r9, {{.*}}
68 ; LINUX-X32-DAG: movb %al, {{.*}}
69 ; LINUX-X32-DAG: movaps %xmm0, {{[0-9]*}}(%esp)
70 ; LINUX-X32-DAG: movaps %xmm1, {{[0-9]*}}(%esp)
71 ; LINUX-X32-DAG: movaps %xmm2, {{[0-9]*}}(%esp)
72 ; LINUX-X32-DAG: movaps %xmm3, {{[0-9]*}}(%esp)
73 ; LINUX-X32-DAG: movaps %xmm4, {{[0-9]*}}(%esp)
74 ; LINUX-X32-DAG: movaps %xmm5, {{[0-9]*}}(%esp)
75 ; LINUX-X32-DAG: movaps %xmm6, {{[0-9]*}}(%esp)
76 ; LINUX-X32-DAG: movaps %xmm7, {{[0-9]*}}(%esp)
77 ; LINUX-X32: callq get_f
78 ; LINUX-X32-DAG: movaps {{[0-9]*}}(%esp), %xmm0
79 ; LINUX-X32-DAG: movaps {{[0-9]*}}(%esp), %xmm1
80 ; LINUX-X32-DAG: movaps {{[0-9]*}}(%esp), %xmm2
81 ; LINUX-X32-DAG: movaps {{[0-9]*}}(%esp), %xmm3
82 ; LINUX-X32-DAG: movaps {{[0-9]*}}(%esp), %xmm4
83 ; LINUX-X32-DAG: movaps {{[0-9]*}}(%esp), %xmm5
84 ; LINUX-X32-DAG: movaps {{[0-9]*}}(%esp), %xmm6
85 ; LINUX-X32-DAG: movaps {{[0-9]*}}(%esp), %xmm7
86 ; LINUX-X32-DAG: movl {{.*}}, %edi
87 ; LINUX-X32-DAG: movq {{.*}}, %rsi
88 ; LINUX-X32-DAG: movq {{.*}}, %rdx
89 ; LINUX-X32-DAG: movq {{.*}}, %rcx
90 ; LINUX-X32-DAG: movq {{.*}}, %r8
91 ; LINUX-X32-DAG: movq {{.*}}, %r9
92 ; LINUX-X32-DAG: movb {{.*}}, %al
93 ; LINUX-X32: jmpq *{{.*}} # TAILCALL
94
60 ; WINDOWS-LABEL: f_thunk: 95 ; WINDOWS-LABEL: f_thunk:
61 ; WINDOWS-NOT: mov{{.}}ps 96 ; WINDOWS-NOT: mov{{.}}ps
62 ; WINDOWS-DAG: movq %rdx, {{.*}} 97 ; WINDOWS-DAG: movq %rdx, {{.*}}
63 ; WINDOWS-DAG: movq %rcx, {{.*}} 98 ; WINDOWS-DAG: movq %rcx, {{.*}}
64 ; WINDOWS-DAG: movq %r8, {{.*}} 99 ; WINDOWS-DAG: movq %r8, {{.*}}
82 ; This thunk shouldn't require any spills and reloads, assuming the register 117 ; This thunk shouldn't require any spills and reloads, assuming the register
83 ; allocator knows what it's doing. 118 ; allocator knows what it's doing.
84 119
85 define void @g_thunk(i8* %fptr_i8, ...) { 120 define void @g_thunk(i8* %fptr_i8, ...) {
86 %fptr = bitcast i8* %fptr_i8 to void (i8*, ...)* 121 %fptr = bitcast i8* %fptr_i8 to void (i8*, ...)*
87 musttail call void (i8*, ...)* %fptr(i8* %fptr_i8, ...) 122 musttail call void (i8*, ...) %fptr(i8* %fptr_i8, ...)
88 ret void 123 ret void
89 } 124 }
90 125
91 ; LINUX-LABEL: g_thunk: 126 ; LINUX-LABEL: g_thunk:
92 ; LINUX-NOT: movq 127 ; LINUX-NOT: movq
93 ; LINUX: jmpq *%rdi # TAILCALL 128 ; LINUX: jmpq *%rdi # TAILCALL
129
130 ; LINUX-X32-LABEL: g_thunk:
131 ; LINUX-X32-DAG: movl %edi, %[[REG:e[abcd]x|ebp|esi|edi|r8|r9|r1[0-5]]]
132 ; LINUX-X32-DAG: jmpq *%[[REG]] # TAILCALL
94 133
95 ; WINDOWS-LABEL: g_thunk: 134 ; WINDOWS-LABEL: g_thunk:
96 ; WINDOWS-NOT: movq 135 ; WINDOWS-NOT: movq
97 ; WINDOWS: jmpq *%rcx # TAILCALL 136 ; WINDOWS: jmpq *%rcx # TAILCALL
98 137
104 %struct.Foo = type { i1, i8*, i8* } 143 %struct.Foo = type { i1, i8*, i8* }
105 144
106 @g = external global i32 145 @g = external global i32
107 146
108 define void @h_thunk(%struct.Foo* %this, ...) { 147 define void @h_thunk(%struct.Foo* %this, ...) {
109 %cond_p = getelementptr %struct.Foo* %this, i32 0, i32 0 148 %cond_p = getelementptr %struct.Foo, %struct.Foo* %this, i32 0, i32 0
110 %cond = load i1* %cond_p 149 %cond = load i1, i1* %cond_p
111 br i1 %cond, label %then, label %else 150 br i1 %cond, label %then, label %else
112 151
113 then: 152 then:
114 %a_p = getelementptr %struct.Foo* %this, i32 0, i32 1 153 %a_p = getelementptr %struct.Foo, %struct.Foo* %this, i32 0, i32 1
115 %a_i8 = load i8** %a_p 154 %a_i8 = load i8*, i8** %a_p
116 %a = bitcast i8* %a_i8 to void (%struct.Foo*, ...)* 155 %a = bitcast i8* %a_i8 to void (%struct.Foo*, ...)*
117 musttail call void (%struct.Foo*, ...)* %a(%struct.Foo* %this, ...) 156 musttail call void (%struct.Foo*, ...) %a(%struct.Foo* %this, ...)
118 ret void 157 ret void
119 158
120 else: 159 else:
121 %b_p = getelementptr %struct.Foo* %this, i32 0, i32 2 160 %b_p = getelementptr %struct.Foo, %struct.Foo* %this, i32 0, i32 2
122 %b_i8 = load i8** %b_p 161 %b_i8 = load i8*, i8** %b_p
123 %b = bitcast i8* %b_i8 to void (%struct.Foo*, ...)* 162 %b = bitcast i8* %b_i8 to void (%struct.Foo*, ...)*
124 store i32 42, i32* @g 163 store i32 42, i32* @g
125 musttail call void (%struct.Foo*, ...)* %b(%struct.Foo* %this, ...) 164 musttail call void (%struct.Foo*, ...) %b(%struct.Foo* %this, ...)
126 ret void 165 ret void
127 } 166 }
128 167
129 ; LINUX-LABEL: h_thunk: 168 ; LINUX-LABEL: h_thunk:
130 ; LINUX: jne 169 ; LINUX: jne
131 ; LINUX: jmpq *{{.*}} # TAILCALL 170 ; LINUX: jmpq *{{.*}} # TAILCALL
132 ; LINUX: jmpq *{{.*}} # TAILCALL 171 ; LINUX: jmpq *{{.*}} # TAILCALL
172 ; LINUX-X32-LABEL: h_thunk:
173 ; LINUX-X32: jne
174 ; LINUX-X32: jmpq *{{.*}} # TAILCALL
175 ; LINUX-X32: jmpq *{{.*}} # TAILCALL
133 ; WINDOWS-LABEL: h_thunk: 176 ; WINDOWS-LABEL: h_thunk:
134 ; WINDOWS: jne 177 ; WINDOWS: jne
135 ; WINDOWS: jmpq *{{.*}} # TAILCALL 178 ; WINDOWS: jmpq *{{.*}} # TAILCALL
136 ; WINDOWS: jmpq *{{.*}} # TAILCALL 179 ; WINDOWS: jmpq *{{.*}} # TAILCALL
137 ; X86-LABEL: _h_thunk: 180 ; X86-LABEL: _h_thunk: