Use symbolic operands in the patchpoint folding routine and fix a spilling bug.
[oota-llvm.git] / test / CodeGen / X86 / anyregcc.ll
1 ; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s
2
3 ; Stackmap Header: no constants - 6 callsites
4 ; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps
5 ; CHECK-NEXT:  __LLVM_StackMaps:
6 ; Header
7 ; CHECK-NEXT:   .long   0
8 ; Num Constants
9 ; CHECK-NEXT:   .long   0
10 ; Num Callsites
11 ; CHECK-NEXT:   .long   8
12
13 ; test
14 ; CHECK-NEXT:   .long   0
15 ; CHECK-LABEL:  .long   L{{.*}}-_test
16 ; CHECK-NEXT:   .short  0
17 ; 3 locations
18 ; CHECK-NEXT:   .short  3
19 ; Loc 0: Register
20 ; CHECK-NEXT:   .byte 1
21 ; CHECK-NEXT:   .byte 4
22 ; CHECK-NEXT:   .short {{[0-9]+}}
23 ; CHECK-NEXT:   .long 0
24 ; Loc 1: Register
25 ; CHECK-NEXT:   .byte 1
26 ; CHECK-NEXT:   .byte 4
27 ; CHECK-NEXT:   .short {{[0-9]+}}
28 ; CHECK-NEXT:   .long 0
29 ; Loc 2: Constant 3
30 ; CHECK-NEXT:   .byte 4
31 ; CHECK-NEXT:   .byte 8
32 ; CHECK-NEXT:   .short  0
33 ; CHECK-NEXT:   .long 3
34 define i64 @test() nounwind ssp uwtable {
35 entry:
36   call anyregcc void (i32, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i32 0, i32 15, i8* null, i32 2, i32 1, i32 2, i64 3)
37   ret i64 0
38 }
39
40 ; property access 1 - %obj is an anyreg call argument and should therefore be in a register
41 ; CHECK-NEXT:   .long   1
42 ; CHECK-LABEL:  .long   L{{.*}}-_property_access1
43 ; CHECK-NEXT:   .short  0
44 ; 2 locations
45 ; CHECK-NEXT:   .short  2
46 ; Loc 0: Register <-- this is the return register
47 ; CHECK-NEXT:   .byte 1
48 ; CHECK-NEXT:   .byte 8
49 ; CHECK-NEXT:   .short {{[0-9]+}}
50 ; CHECK-NEXT:   .long 0
51 ; Loc 1: Register
52 ; CHECK-NEXT:   .byte 1
53 ; CHECK-NEXT:   .byte 8
54 ; CHECK-NEXT:   .short {{[0-9]+}}
55 ; CHECK-NEXT:   .long 0
56 define i64 @property_access1(i8* %obj) nounwind ssp uwtable {
57 entry:
58   %f = inttoptr i64 12297829382473034410 to i8*
59   %ret = call anyregcc i64 (i32, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i32 1, i32 15, i8* %f, i32 1, i8* %obj)
60   ret i64 %ret
61 }
62
63 ; property access 2 - %obj is an anyreg call argument and should therefore be in a register
64 ; CHECK-NEXT:   .long   2
65 ; CHECK-LABEL:  .long   L{{.*}}-_property_access2
66 ; CHECK-NEXT:   .short  0
67 ; 2 locations
68 ; CHECK-NEXT:   .short  2
69 ; Loc 0: Register <-- this is the return register
70 ; CHECK-NEXT:   .byte 1
71 ; CHECK-NEXT:   .byte 8
72 ; CHECK-NEXT:   .short {{[0-9]+}}
73 ; CHECK-NEXT:   .long 0
74 ; Loc 1: Register
75 ; CHECK-NEXT:   .byte 1
76 ; CHECK-NEXT:   .byte 8
77 ; CHECK-NEXT:   .short {{[0-9]+}}
78 ; CHECK-NEXT:   .long 0
79 define i64 @property_access2() nounwind ssp uwtable {
80 entry:
81   %obj = alloca i64, align 8
82   %f = inttoptr i64 12297829382473034410 to i8*
83   %ret = call anyregcc i64 (i32, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i32 2, i32 15, i8* %f, i32 1, i64* %obj)
84   ret i64 %ret
85 }
86
87 ; property access 3 - %obj is a frame index
88 ; CHECK-NEXT:   .long   3
89 ; CHECK-LABEL:  .long   L{{.*}}-_property_access3
90 ; CHECK-NEXT:   .short  0
91 ; 2 locations
92 ; CHECK-NEXT:   .short  2
93 ; Loc 0: Register <-- this is the return register
94 ; CHECK-NEXT:   .byte 1
95 ; CHECK-NEXT:   .byte 8
96 ; CHECK-NEXT:   .short {{[0-9]+}}
97 ; CHECK-NEXT:   .long 0
98 ; Loc 1: Register <-- this will be folded once folding for FI is implemented
99 ; CHECK-NEXT:   .byte 1
100 ; CHECK-NEXT:   .byte 8
101 ; CHECK-NEXT:   .short {{[0-9]+}}
102 ; CHECK-NEXT:   .long 0
103 define i64 @property_access3() nounwind ssp uwtable {
104 entry:
105   %obj = alloca i64, align 8
106   %f = inttoptr i64 12297829382473034410 to i8*
107   %ret = call anyregcc i64 (i32, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i32 3, i32 15, i8* %f, i32 0, i64* %obj)
108   ret i64 %ret
109 }
110
111 ; anyreg_test1
112 ; CHECK-NEXT:   .long   4
113 ; CHECK-LABEL:  .long   L{{.*}}-_anyreg_test1
114 ; CHECK-NEXT:   .short  0
115 ; 14 locations
116 ; CHECK-NEXT:   .short  14
117 ; Loc 0: Register <-- this is the return register
118 ; CHECK-NEXT:   .byte 1
119 ; CHECK-NEXT:   .byte 8
120 ; CHECK-NEXT:   .short {{[0-9]+}}
121 ; CHECK-NEXT:   .long 0
122 ; Loc 1: Register
123 ; CHECK-NEXT:   .byte 1
124 ; CHECK-NEXT:   .byte 8
125 ; CHECK-NEXT:   .short {{[0-9]+}}
126 ; CHECK-NEXT:   .long 0
127 ; Loc 2: Register
128 ; CHECK-NEXT:   .byte 1
129 ; CHECK-NEXT:   .byte 8
130 ; CHECK-NEXT:   .short {{[0-9]+}}
131 ; CHECK-NEXT:   .long 0
132 ; Loc 3: Register
133 ; CHECK-NEXT:   .byte 1
134 ; CHECK-NEXT:   .byte 8
135 ; CHECK-NEXT:   .short {{[0-9]+}}
136 ; CHECK-NEXT:   .long 0
137 ; Loc 4: Register
138 ; CHECK-NEXT:   .byte 1
139 ; CHECK-NEXT:   .byte 8
140 ; CHECK-NEXT:   .short {{[0-9]+}}
141 ; CHECK-NEXT:   .long 0
142 ; Loc 5: Register
143 ; CHECK-NEXT:   .byte 1
144 ; CHECK-NEXT:   .byte 8
145 ; CHECK-NEXT:   .short {{[0-9]+}}
146 ; CHECK-NEXT:   .long 0
147 ; Loc 6: Register
148 ; CHECK-NEXT:   .byte 1
149 ; CHECK-NEXT:   .byte 8
150 ; CHECK-NEXT:   .short {{[0-9]+}}
151 ; CHECK-NEXT:   .long 0
152 ; Loc 7: Register
153 ; CHECK-NEXT:   .byte 1
154 ; CHECK-NEXT:   .byte 8
155 ; CHECK-NEXT:   .short {{[0-9]+}}
156 ; CHECK-NEXT:   .long 0
157 ; Loc 8: Register
158 ; CHECK-NEXT:   .byte 1
159 ; CHECK-NEXT:   .byte 8
160 ; CHECK-NEXT:   .short {{[0-9]+}}
161 ; CHECK-NEXT:   .long 0
162 ; Loc 9: Register
163 ; CHECK-NEXT:   .byte 1
164 ; CHECK-NEXT:   .byte 8
165 ; CHECK-NEXT:   .short {{[0-9]+}}
166 ; CHECK-NEXT:   .long 0
167 ; Loc 10: Register
168 ; CHECK-NEXT:   .byte 1
169 ; CHECK-NEXT:   .byte 8
170 ; CHECK-NEXT:   .short {{[0-9]+}}
171 ; CHECK-NEXT:   .long 0
172 ; Loc 11: Register
173 ; CHECK-NEXT:   .byte 1
174 ; CHECK-NEXT:   .byte 8
175 ; CHECK-NEXT:   .short {{[0-9]+}}
176 ; CHECK-NEXT:   .long 0
177 ; Loc 12: Register
178 ; CHECK-NEXT:   .byte 1
179 ; CHECK-NEXT:   .byte 8
180 ; CHECK-NEXT:   .short {{[0-9]+}}
181 ; CHECK-NEXT:   .long 0
182 ; Loc 13: Register
183 ; CHECK-NEXT:   .byte 1
184 ; CHECK-NEXT:   .byte 8
185 ; CHECK-NEXT:   .short {{[0-9]+}}
186 ; CHECK-NEXT:   .long 0
187 define i64 @anyreg_test1(i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13) nounwind ssp uwtable {
188 entry:
189   %f = inttoptr i64 12297829382473034410 to i8*
190   %ret = call anyregcc i64 (i32, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i32 4, i32 15, i8* %f, i32 13, i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13)
191   ret i64 %ret
192 }
193
194 ; anyreg_test2
195 ; CHECK-NEXT:   .long   5
196 ; CHECK-LABEL:  .long   L{{.*}}-_anyreg_test2
197 ; CHECK-NEXT:   .short  0
198 ; 14 locations
199 ; CHECK-NEXT:   .short  14
200 ; Loc 0: Register <-- this is the return register
201 ; CHECK-NEXT:   .byte 1
202 ; CHECK-NEXT:   .byte 8
203 ; CHECK-NEXT:   .short {{[0-9]+}}
204 ; CHECK-NEXT:   .long 0
205 ; Loc 1: Register
206 ; CHECK-NEXT:   .byte 1
207 ; CHECK-NEXT:   .byte 8
208 ; CHECK-NEXT:   .short {{[0-9]+}}
209 ; CHECK-NEXT:   .long 0
210 ; Loc 2: Register
211 ; CHECK-NEXT:   .byte 1
212 ; CHECK-NEXT:   .byte 8
213 ; CHECK-NEXT:   .short {{[0-9]+}}
214 ; CHECK-NEXT:   .long 0
215 ; Loc 3: Register
216 ; CHECK-NEXT:   .byte 1
217 ; CHECK-NEXT:   .byte 8
218 ; CHECK-NEXT:   .short {{[0-9]+}}
219 ; CHECK-NEXT:   .long 0
220 ; Loc 4: Register
221 ; CHECK-NEXT:   .byte 1
222 ; CHECK-NEXT:   .byte 8
223 ; CHECK-NEXT:   .short {{[0-9]+}}
224 ; CHECK-NEXT:   .long 0
225 ; Loc 5: Register
226 ; CHECK-NEXT:   .byte 1
227 ; CHECK-NEXT:   .byte 8
228 ; CHECK-NEXT:   .short {{[0-9]+}}
229 ; CHECK-NEXT:   .long 0
230 ; Loc 6: Register
231 ; CHECK-NEXT:   .byte 1
232 ; CHECK-NEXT:   .byte 8
233 ; CHECK-NEXT:   .short {{[0-9]+}}
234 ; CHECK-NEXT:   .long 0
235 ; Loc 7: Register
236 ; CHECK-NEXT:   .byte 1
237 ; CHECK-NEXT:   .byte 8
238 ; CHECK-NEXT:   .short {{[0-9]+}}
239 ; CHECK-NEXT:   .long 0
240 ; Loc 8: Register
241 ; CHECK-NEXT:   .byte 1
242 ; CHECK-NEXT:   .byte 8
243 ; CHECK-NEXT:   .short {{[0-9]+}}
244 ; CHECK-NEXT:   .long 0
245 ; Loc 9: Register
246 ; CHECK-NEXT:   .byte 1
247 ; CHECK-NEXT:   .byte 8
248 ; CHECK-NEXT:   .short {{[0-9]+}}
249 ; CHECK-NEXT:   .long 0
250 ; Loc 10: Register
251 ; CHECK-NEXT:   .byte 1
252 ; CHECK-NEXT:   .byte 8
253 ; CHECK-NEXT:   .short {{[0-9]+}}
254 ; CHECK-NEXT:   .long 0
255 ; Loc 11: Register
256 ; CHECK-NEXT:   .byte 1
257 ; CHECK-NEXT:   .byte 8
258 ; CHECK-NEXT:   .short {{[0-9]+}}
259 ; CHECK-NEXT:   .long 0
260 ; Loc 12: Register
261 ; CHECK-NEXT:   .byte 1
262 ; CHECK-NEXT:   .byte 8
263 ; CHECK-NEXT:   .short {{[0-9]+}}
264 ; CHECK-NEXT:   .long 0
265 ; Loc 13: Register
266 ; CHECK-NEXT:   .byte 1
267 ; CHECK-NEXT:   .byte 8
268 ; CHECK-NEXT:   .short {{[0-9]+}}
269 ; CHECK-NEXT:   .long 0
270 define i64 @anyreg_test2(i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13) nounwind ssp uwtable {
271 entry:
272   %f = inttoptr i64 12297829382473034410 to i8*
273   %ret = call anyregcc i64 (i32, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i32 5, i32 15, i8* %f, i32 8, i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13)
274   ret i64 %ret
275 }
276
277 ; Test spilling the return value of an anyregcc call.
278 ;
279 ; <rdar://problem/15432754> [JS] Assertion: "Folded a def to a non-store!"
280 ;
281 ; CHECK-LABEL: .long 12
282 ; CHECK-LABEL: .long L{{.*}}-_patchpoint_spilldef
283 ; CHECK-NEXT: .short 0
284 ; CHECK-NEXT: .short 3
285 ; Loc 0: Register (some register that will be spilled to the stack)
286 ; CHECK-NEXT: .byte  1
287 ; CHECK-NEXT: .byte  8
288 ; CHECK-NEXT: .short {{[0-9]+}}
289 ; CHECK-NEXT: .long  0
290 ; Loc 1: Register RDI
291 ; CHECK-NEXT: .byte  1
292 ; CHECK-NEXT: .byte  8
293 ; CHECK-NEXT: .short 5
294 ; CHECK-NEXT: .long  0
295 ; Loc 1: Register RSI
296 ; CHECK-NEXT: .byte  1
297 ; CHECK-NEXT: .byte  8
298 ; CHECK-NEXT: .short 4
299 ; CHECK-NEXT: .long  0
300 define i64 @patchpoint_spilldef(i64 %p1, i64 %p2, i64 %p3, i64 %p4) {
301 entry:
302   %result = tail call anyregcc i64 (i32, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i32 12, i32 15, i8* inttoptr (i64 0 to i8*), i32 2, i64 %p1, i64 %p2)
303   tail call void asm sideeffect "nop", "~{ax},~{bx},~{cx},~{dx},~{bp},~{si},~{di},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"() nounwind
304   ret i64 %result
305 }
306
307 ; Test spilling the arguments of an anyregcc call.
308 ;
309 ; <rdar://problem/15487687> [JS] AnyRegCC argument ends up being spilled
310 ;
311 ; CHECK-LABEL: .long 13
312 ; CHECK-LABEL: .long L{{.*}}-_patchpoint_spillargs
313 ; CHECK-NEXT: .short 0
314 ; CHECK-NEXT: .short 5
315 ; Loc 0: Return a register
316 ; CHECK-NEXT: .byte  1
317 ; CHECK-NEXT: .byte  8
318 ; CHECK-NEXT: .short {{[0-9]+}}
319 ; CHECK-NEXT: .long  0
320 ; Loc 1: Arg0 in a Register
321 ; CHECK-NEXT: .byte  1
322 ; CHECK-NEXT: .byte  8
323 ; CHECK-NEXT: .short {{[0-9]+}}
324 ; CHECK-NEXT: .long  0
325 ; Loc 2: Arg1 in a Register
326 ; CHECK-NEXT: .byte  1
327 ; CHECK-NEXT: .byte  8
328 ; CHECK-NEXT: .short {{[0-9]+}}
329 ; CHECK-NEXT: .long  0
330 ; Loc 3: Arg2 spilled to RBP +
331 ; CHECK-NEXT: .byte  3
332 ; CHECK-NEXT: .byte  8
333 ; CHECK-NEXT: .short 7
334 ; CHECK-NEXT: .long  {{[0-9]+}}
335 ; Loc 4: Arg3 spilled to RBP +
336 ; CHECK-NEXT: .byte  3
337 ; CHECK-NEXT: .byte  8
338 ; CHECK-NEXT: .short 7
339 ; CHECK-NEXT: .long  {{[0-9]+}}
340 define i64 @patchpoint_spillargs(i64 %p1, i64 %p2, i64 %p3, i64 %p4) {
341 entry:
342   tail call void asm sideeffect "nop", "~{ax},~{bx},~{cx},~{dx},~{bp},~{si},~{di},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"() nounwind
343   %result = tail call anyregcc i64 (i32, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i32 13, i32 15, i8* inttoptr (i64 0 to i8*), i32 2, i64 %p1, i64 %p2, i64 %p3, i64 %p4)
344   ret i64 %result
345 }
346
347 declare void @llvm.experimental.patchpoint.void(i32, i32, i8*, i32, ...)
348 declare i64 @llvm.experimental.patchpoint.i64(i32, i32, i8*, i32, ...)