Mercurial > hg > CbC > CbC_llvm
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: |