Add a new attribute called 'jumptable' that creates jump-instruction tables for funct...
[oota-llvm.git] / test / CodeGen / X86 / jump_tables.ll
1 ; RUN: llc <%s -jump-table-type=single | FileCheck --check-prefix=SINGLE %s
2 ; RUN: llc <%s -jump-table-type=arity | FileCheck --check-prefix=ARITY %s
3 ; RUN: llc <%s -jump-table-type=simplified | FileCheck --check-prefix=SIMPL %s
4 ; RUN: llc <%s -jump-table-type=full | FileCheck --check-prefix=FULL %s
5
6 target triple = "x86_64-unknown-linux-gnu"
7
8 %struct.fun_struct = type { i32 (...)* }
9
10 define void @indirect_fun() unnamed_addr jumptable {
11   ret void
12 }
13
14 define void @indirect_fun_match() unnamed_addr jumptable {
15   ret void
16 }
17
18 define i32 @indirect_fun_i32() unnamed_addr jumptable {
19   ret i32 0
20 }
21
22 define i32 @indirect_fun_i32_1(i32 %a) unnamed_addr jumptable {
23   ret i32 %a
24 }
25
26 define i32 @indirect_fun_i32_2(i32 %a, i32 %b) unnamed_addr jumptable {
27   ret i32 %a
28 }
29
30 define i32* @indirect_fun_i32S_2(i32* %a, i32 %b) unnamed_addr jumptable {
31   ret i32* %a
32 }
33
34 define void @indirect_fun_struct(%struct.fun_struct %fs) unnamed_addr jumptable {
35   ret void
36 }
37
38 define void @indirect_fun_fun(i32 (...)* %fun, i32 %a) unnamed_addr jumptable {
39   ret void
40 }
41
42 define i32 @indirect_fun_fun_ret(i32 (...)* %fun, i32 %a) unnamed_addr jumptable {
43   ret i32 %a
44 }
45
46 define void @indirect_fun_array([19 x i8] %a) unnamed_addr jumptable {
47   ret void
48 }
49
50 define void @indirect_fun_vec(<3 x i32> %a) unnamed_addr jumptable {
51   ret void
52 }
53
54 define void @indirect_fun_vec_2(<4 x float> %a) unnamed_addr jumptable {
55   ret void
56 }
57
58 define i32 @m(void ()* %fun) {
59   call void ()* %fun()
60   ret i32 0
61 }
62
63 define void ()* @get_fun() {
64   ret void ()* @indirect_fun
65 ; SINGLE: movl    $__llvm_jump_instr_table_0_
66 ; ARITY: movl    $__llvm_jump_instr_table_
67 ; SIMPL: movl    $__llvm_jump_instr_table_
68 ; FULL: movl    $__llvm_jump_instr_table_
69 }
70
71 define i32 @main(i32 %argc, i8** %argv) {
72   %f = call void ()* ()* @get_fun()
73   %a = call i32 @m(void ()* %f)
74   ret i32 %a
75 }
76
77 ; SINGLE-DAG:         .globl  __llvm_jump_instr_table_0_1
78 ; SINGLE-DAG:         .align  8, 0x90
79 ; SINGLE-DAG:         .type   __llvm_jump_instr_table_0_1,@function
80 ; SINGLE-DAG: __llvm_jump_instr_table_0_1:
81 ; SINGLE-DAG:         jmp     indirect_fun_array@PLT
82 ; SINGLE-DAG:         .globl  __llvm_jump_instr_table_0_2
83 ; SINGLE-DAG:         .align  8, 0x90
84 ; SINGLE-DAG:         .type   __llvm_jump_instr_table_0_2,@function
85 ; SINGLE-DAG: __llvm_jump_instr_table_0_2:
86 ; SINGLE-DAG:         jmp     indirect_fun_i32_2@PLT
87 ; SINGLE-DAG:         .globl  __llvm_jump_instr_table_0_3
88 ; SINGLE-DAG:         .align  8, 0x90
89 ; SINGLE-DAG:         .type   __llvm_jump_instr_table_0_3,@function
90 ; SINGLE-DAG: __llvm_jump_instr_table_0_3:
91 ; SINGLE-DAG:         jmp     indirect_fun_vec_2@PLT
92 ; SINGLE-DAG:         .globl  __llvm_jump_instr_table_0_4
93 ; SINGLE-DAG:         .align  8, 0x90
94 ; SINGLE-DAG:         .type   __llvm_jump_instr_table_0_4,@function
95 ; SINGLE-DAG: __llvm_jump_instr_table_0_4:
96 ; SINGLE-DAG:         jmp     indirect_fun_i32S_2@PLT
97 ; SINGLE-DAG:         .globl  __llvm_jump_instr_table_0_5
98 ; SINGLE-DAG:         .align  8, 0x90
99 ; SINGLE-DAG:         .type   __llvm_jump_instr_table_0_5,@function
100 ; SINGLE-DAG: __llvm_jump_instr_table_0_5:
101 ; SINGLE-DAG:         jmp     indirect_fun_struct@PLT
102 ; SINGLE-DAG:         .globl  __llvm_jump_instr_table_0_6
103 ; SINGLE-DAG:         .align  8, 0x90
104 ; SINGLE-DAG:         .type   __llvm_jump_instr_table_0_6,@function
105 ; SINGLE-DAG: __llvm_jump_instr_table_0_6:
106 ; SINGLE-DAG:         jmp     indirect_fun_i32_1@PLT
107 ; SINGLE-DAG:         .globl  __llvm_jump_instr_table_0_7
108 ; SINGLE-DAG:         .align  8, 0x90
109 ; SINGLE-DAG:         .type   __llvm_jump_instr_table_0_7,@function
110 ; SINGLE-DAG: __llvm_jump_instr_table_0_7:
111 ; SINGLE-DAG:         jmp     indirect_fun_i32@PLT
112 ; SINGLE-DAG:         .globl  __llvm_jump_instr_table_0_8
113 ; SINGLE-DAG:         .align  8, 0x90
114 ; SINGLE-DAG:         .type   __llvm_jump_instr_table_0_8,@function
115 ; SINGLE-DAG: __llvm_jump_instr_table_0_8:
116 ; SINGLE-DAG:         jmp     indirect_fun_fun@PLT
117 ; SINGLE-DAG:         .globl  __llvm_jump_instr_table_0_9
118 ; SINGLE-DAG:         .align  8, 0x90
119 ; SINGLE-DAG:         .type   __llvm_jump_instr_table_0_9,@function
120 ; SINGLE-DAG: __llvm_jump_instr_table_0_9:
121 ; SINGLE-DAG:         jmp     indirect_fun_fun_ret@PLT
122 ; SINGLE-DAG:         .globl  __llvm_jump_instr_table_0_10
123 ; SINGLE-DAG:         .align  8, 0x90
124 ; SINGLE-DAG:         .type   __llvm_jump_instr_table_0_10,@function
125 ; SINGLE-DAG: __llvm_jump_instr_table_0_10:
126 ; SINGLE-DAG:         jmp     indirect_fun@PLT
127 ; SINGLE-DAG:         .globl  __llvm_jump_instr_table_0_11
128 ; SINGLE-DAG:         .align  8, 0x90
129 ; SINGLE-DAG:         .type   __llvm_jump_instr_table_0_11,@function
130 ; SINGLE-DAG: __llvm_jump_instr_table_0_11:
131 ; SINGLE-DAG:         jmp     indirect_fun_match@PLT
132 ; SINGLE-DAG:         .globl  __llvm_jump_instr_table_0_12
133 ; SINGLE-DAG:         .align  8, 0x90
134 ; SINGLE-DAG:         .type   __llvm_jump_instr_table_0_12,@function
135 ; SINGLE-DAG: __llvm_jump_instr_table_0_12:
136 ; SINGLE-DAG:         jmp     indirect_fun_vec@PLT
137 ; SINGLE-DAG:         .align  8, 0x90
138 ; SINGLE-DAG:         ud2
139 ; SINGLE-DAG:         .align  8, 0x90
140 ; SINGLE-DAG:         ud2
141 ; SINGLE-DAG:         .align  8, 0x90
142 ; SINGLE-DAG:         ud2
143 ; SINGLE-DAG:         .align  8, 0x90
144 ; SINGLE-DAG:         ud2
145
146
147 ; ARITY-DAG:         .globl  __llvm_jump_instr_table_2_1
148 ; ARITY-DAG:         .align  8, 0x90
149 ; ARITY-DAG:         .type   __llvm_jump_instr_table_2_1,@function
150 ; ARITY-DAG: __llvm_jump_instr_table_2_1:
151 ; ARITY-DAG:         jmp     indirect_fun{{.*}}@PLT
152 ; ARITY-DAG:         .align  8, 0x90
153 ; ARITY-DAG:         ud2
154 ; ARITY-DAG:         .globl  __llvm_jump_instr_table_0_1
155 ; ARITY-DAG:         .align  8, 0x90
156 ; ARITY-DAG:         .type   __llvm_jump_instr_table_0_1,@function
157 ; ARITY-DAG: __llvm_jump_instr_table_0_1:
158 ; ARITY-DAG:         jmp     indirect_fun{{.*}}@PLT
159 ; ARITY-DAG:         .globl  __llvm_jump_instr_table_1_1
160 ; ARITY-DAG:         .align  8, 0x90
161 ; ARITY-DAG:         .type   __llvm_jump_instr_table_1_1,@function
162 ; ARITY-DAG: __llvm_jump_instr_table_1_1:
163 ; ARITY-DAG:         jmp     indirect_fun{{.*}}@PLT
164
165 ; SIMPL-DAG:         .globl  __llvm_jump_instr_table_2_1
166 ; SIMPL-DAG:         .align  8, 0x90
167 ; SIMPL-DAG:         .type   __llvm_jump_instr_table_2_1,@function
168 ; SIMPL-DAG: __llvm_jump_instr_table_2_1:
169 ; SIMPL-DAG:         jmp     indirect_fun{{.*}}@PLT
170 ; SIMPL-DAG:         .align  8, 0x90
171 ; SIMPL-DAG:         ud2
172 ; SIMPL-DAG:         .globl  __llvm_jump_instr_table_0_1
173 ; SIMPL-DAG:         .align  8, 0x90
174 ; SIMPL-DAG:         .type   __llvm_jump_instr_table_0_1,@function
175 ; SIMPL-DAG: __llvm_jump_instr_table_0_1:
176 ; SIMPL-DAG:         jmp     indirect_fun{{.*}}@PLT
177 ; SIMPL-DAG:         .globl  __llvm_jump_instr_table_1_1
178 ; SIMPL-DAG:         .align  8, 0x90
179 ; SIMPL-DAG:         .type   __llvm_jump_instr_table_1_1,@function
180 ; SIMPL-DAG: __llvm_jump_instr_table_1_1:
181 ; SIMPL-DAG:         jmp     indirect_fun{{.*}}@PLT
182 ; SIMPL-DAG:         .globl  __llvm_jump_instr_table_3_1
183 ; SIMPL-DAG:         .align  8, 0x90
184 ; SIMPL-DAG:         .type   __llvm_jump_instr_table_3_1,@function
185 ; SIMPL-DAG: __llvm_jump_instr_table_3_1:
186 ; SIMPL-DAG:         jmp     indirect_fun{{.*}}@PLT
187 ; SIMPL-DAG:         .globl  __llvm_jump_instr_table_4_1
188 ; SIMPL-DAG:         .align  8, 0x90
189 ; SIMPL-DAG:         .type   __llvm_jump_instr_table_4_1,@function
190 ; SIMPL-DAG: __llvm_jump_instr_table_4_1:
191 ; SIMPL-DAG:         jmp     indirect_fun{{.*}}@PLT
192
193
194 ; FULL-DAG:        .globl  __llvm_jump_instr_table_10_1
195 ; FULL-DAG:        .align  8, 0x90
196 ; FULL-DAG:        .type   __llvm_jump_instr_table_10_1,@function
197 ; FULL-DAG:__llvm_jump_instr_table_10_1:
198 ; FULL-DAG:        jmp     indirect_fun_i32_1@PLT
199 ; FULL-DAG:        .align  8, 0x90
200 ; FULL-DAG:        ud2
201 ; FULL-DAG:        .globl  __llvm_jump_instr_table_9_1
202 ; FULL-DAG:        .align  8, 0x90
203 ; FULL-DAG:        .type   __llvm_jump_instr_table_9_1,@function
204 ; FULL-DAG:__llvm_jump_instr_table_9_1:
205 ; FULL-DAG:        jmp     indirect_fun_i32_2@PLT
206 ; FULL-DAG:        .align  8, 0x90
207 ; FULL-DAG:        ud2
208 ; FULL-DAG:        .globl  __llvm_jump_instr_table_7_1
209 ; FULL-DAG:        .align  8, 0x90
210 ; FULL-DAG:        .type   __llvm_jump_instr_table_7_1,@function
211 ; FULL-DAG:__llvm_jump_instr_table_7_1:
212 ; FULL-DAG:        jmp     indirect_fun_i32S_2@PLT
213 ; FULL-DAG:        .align  8, 0x90
214 ; FULL-DAG:        ud2
215 ; FULL-DAG:        .globl  __llvm_jump_instr_table_3_1
216 ; FULL-DAG:        .align  8, 0x90
217 ; FULL-DAG:        .type   __llvm_jump_instr_table_3_1,@function
218 ; FULL-DAG:__llvm_jump_instr_table_3_1:
219 ; FULL-DAG:        jmp     indirect_fun_vec_2@PLT
220 ; FULL-DAG:        .align  8, 0x90
221 ; FULL-DAG:        ud2
222 ; FULL-DAG:        .globl  __llvm_jump_instr_table_2_1
223 ; FULL-DAG:        .align  8, 0x90
224 ; FULL-DAG:        .type   __llvm_jump_instr_table_2_1,@function
225 ; FULL-DAG:__llvm_jump_instr_table_2_1:
226 ; FULL-DAG:        jmp     indirect_fun@PLT
227 ; FULL-DAG:        .align  8, 0x90
228 ; FULL-DAG:        ud2
229 ; FULL-DAG:        .align  8, 0x90
230 ; FULL-DAG:        ud2
231 ; FULL-DAG:        .globl  __llvm_jump_instr_table_8_1
232 ; FULL-DAG:        .align  8, 0x90
233 ; FULL-DAG:        .type   __llvm_jump_instr_table_8_1,@function
234 ; FULL-DAG:__llvm_jump_instr_table_8_1:
235 ; FULL-DAG:        jmp     indirect_fun_i32@PLT
236 ; FULL-DAG:        .align  8, 0x90
237 ; FULL-DAG:        ud2
238 ; FULL-DAG:        .globl  __llvm_jump_instr_table_1_1
239 ; FULL-DAG:        .align  8, 0x90
240 ; FULL-DAG:        .type   __llvm_jump_instr_table_1_1,@function
241 ; FULL-DAG:__llvm_jump_instr_table_1_1:
242 ; FULL-DAG:        jmp     indirect_fun_array@PLT
243 ; FULL-DAG:        .align  8, 0x90
244 ; FULL-DAG:        ud2
245 ; FULL-DAG:        .globl  __llvm_jump_instr_table_0_1
246 ; FULL-DAG:        .align  8, 0x90
247 ; FULL-DAG:        .type   __llvm_jump_instr_table_0_1,@function
248 ; FULL-DAG:__llvm_jump_instr_table_0_1:
249 ; FULL-DAG:        jmp     indirect_fun_vec@PLT
250 ; FULL-DAG:        .align  8, 0x90
251 ; FULL-DAG:        ud2
252 ; FULL-DAG:        .globl  __llvm_jump_instr_table_6_1
253 ; FULL-DAG:        .align  8, 0x90
254 ; FULL-DAG:        .type   __llvm_jump_instr_table_6_1,@function
255 ; FULL-DAG:__llvm_jump_instr_table_6_1:
256 ; FULL-DAG:        jmp     indirect_fun_struct@PLT
257 ; FULL-DAG:        .align  8, 0x90
258 ; FULL-DAG:        ud2
259 ; FULL-DAG:        .globl  __llvm_jump_instr_table_5_1
260 ; FULL-DAG:        .align  8, 0x90
261 ; FULL-DAG:        .type   __llvm_jump_instr_table_5_1,@function
262 ; FULL-DAG:__llvm_jump_instr_table_5_1:
263 ; FULL-DAG:        jmp     indirect_fun_fun@PLT
264 ; FULL-DAG:        .align  8, 0x90
265 ; FULL-DAG:        ud2
266 ; FULL-DAG:        .globl  __llvm_jump_instr_table_4_1
267 ; FULL-DAG:        .align  8, 0x90
268 ; FULL-DAG:        .type   __llvm_jump_instr_table_4_1,@function
269 ; FULL-DAG:__llvm_jump_instr_table_4_1:
270 ; FULL-DAG:        jmp     indirect_fun_fun_ret@PLT
271 ; FULL-DAG:        .align  8, 0x90
272 ; FULL-DAG:        ud2