llvm.experimental.stackmap: fix encoding of large constants.
[oota-llvm.git] / test / CodeGen / X86 / stackmap.ll
1 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7 -disable-fp-elim | FileCheck %s
2 ;
3 ; Note: Print verbose stackmaps using -debug-only=stackmaps.
4
5 ; CHECK-LABEL:  .section  __LLVM_STACKMAPS,__llvm_stackmaps
6 ; CHECK-NEXT:  __LLVM_StackMaps:
7 ; CHECK-NEXT:   .long   0
8 ; Num LargeConstants
9 ; CHECK-NEXT:   .long   3
10 ; CHECK-NEXT:   .quad   2147483648
11 ; CHECK-NEXT:   .quad   4294967295
12 ; CHECK-NEXT:   .quad   4294967296
13 ; Num Callsites
14 ; CHECK-NEXT:   .long   18
15
16 ; Constant arguments
17 ;
18 ; CHECK-NEXT:   .quad   1
19 ; CHECK-NEXT:   .long   L{{.*}}-_constantargs
20 ; CHECK-NEXT:   .short  0
21 ; CHECK-NEXT:   .short  12
22 ; SmallConstant
23 ; CHECK-NEXT:   .byte   4
24 ; CHECK-NEXT:   .byte   8
25 ; CHECK-NEXT:   .short  0
26 ; CHECK-NEXT:   .long   -1
27 ; SmallConstant
28 ; CHECK-NEXT:   .byte   4
29 ; CHECK-NEXT:   .byte   8
30 ; CHECK-NEXT:   .short  0
31 ; CHECK-NEXT:   .long   -1
32 ; SmallConstant
33 ; CHECK-NEXT:   .byte   4
34 ; CHECK-NEXT:   .byte   8
35 ; CHECK-NEXT:   .short  0
36 ; CHECK-NEXT:   .long   65536
37 ; SmallConstant
38 ; CHECK-NEXT:   .byte   4
39 ; CHECK-NEXT:   .byte   8
40 ; CHECK-NEXT:   .short  0
41 ; CHECK-NEXT:   .long   2000000000
42 ; SmallConstant
43 ; CHECK-NEXT:   .byte   4
44 ; CHECK-NEXT:   .byte   8
45 ; CHECK-NEXT:   .short  0
46 ; CHECK-NEXT:   .long   2147483647
47 ; SmallConstant
48 ; CHECK-NEXT:   .byte   4
49 ; CHECK-NEXT:   .byte   8
50 ; CHECK-NEXT:   .short  0
51 ; CHECK-NEXT:   .long   -1
52 ; SmallConstant
53 ; CHECK-NEXT:   .byte   4
54 ; CHECK-NEXT:   .byte   8
55 ; CHECK-NEXT:   .short  0
56 ; CHECK-NEXT:   .long   -1
57 ; SmallConstant
58 ; CHECK-NEXT:   .byte   4
59 ; CHECK-NEXT:   .byte   8
60 ; CHECK-NEXT:   .short  0
61 ; CHECK-NEXT:   .long   0
62 ; LargeConstant at index 0
63 ; CHECK-NEXT:   .byte   5
64 ; CHECK-NEXT:   .byte   8
65 ; CHECK-NEXT:   .short  0
66 ; CHECK-NEXT:   .long   0
67 ; LargeConstant at index 1
68 ; CHECK-NEXT:   .byte   5
69 ; CHECK-NEXT:   .byte   8
70 ; CHECK-NEXT:   .short  0
71 ; CHECK-NEXT:   .long   1
72 ; LargeConstant at index 2
73 ; CHECK-NEXT:   .byte   5
74 ; CHECK-NEXT:   .byte   8
75 ; CHECK-NEXT:   .short  0
76 ; CHECK-NEXT:   .long   2
77 ; SmallConstant
78 ; CHECK-NEXT:   .byte   4
79 ; CHECK-NEXT:   .byte   8
80 ; CHECK-NEXT:   .short  0
81 ; CHECK-NEXT:   .long   -1
82
83 define void @constantargs() {
84 entry:
85   %0 = inttoptr i64 12345 to i8*
86   tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 1, i32 15, i8* %0, i32 0, i16 65535, i16 -1, i32 65536, i32 2000000000, i32 2147483647, i32 -1, i32 4294967295, i32 4294967296, i64 2147483648, i64 4294967295, i64 4294967296, i64 -1)
87   ret void
88 }
89
90 ; Inline OSR Exit
91 ;
92 ; CHECK-LABEL:  .long   L{{.*}}-_osrinline
93 ; CHECK-NEXT:   .short  0
94 ; CHECK-NEXT:   .short  2
95 ; CHECK-NEXT:   .byte   1
96 ; CHECK-NEXT:   .byte   8
97 ; CHECK-NEXT:   .short  {{[0-9]+}}
98 ; CHECK-NEXT:   .long   0
99 ; CHECK-NEXT:   .byte   1
100 ; CHECK-NEXT:   .byte   8
101 ; CHECK-NEXT:   .short  {{[0-9]+}}
102 ; CHECK-NEXT:   .long  0
103 define void @osrinline(i64 %a, i64 %b) {
104 entry:
105   ; Runtime void->void call.
106   call void inttoptr (i64 -559038737 to void ()*)()
107   ; Followed by inline OSR patchpoint with 12-byte shadow and 2 live vars.
108   call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 3, i32 12, i64 %a, i64 %b)
109   ret void
110 }
111
112 ; Cold OSR Exit
113 ;
114 ; 2 live variables in register.
115 ;
116 ; CHECK-LABEL:  .long   L{{.*}}-_osrcold
117 ; CHECK-NEXT:   .short  0
118 ; CHECK-NEXT:   .short  2
119 ; CHECK-NEXT:   .byte   1
120 ; CHECK-NEXT:   .byte   8
121 ; CHECK-NEXT:   .short  {{[0-9]+}}
122 ; CHECK-NEXT:   .long   0
123 ; CHECK-NEXT:   .byte   1
124 ; CHECK-NEXT:   .byte   8
125 ; CHECK-NEXT:   .short  {{[0-9]+}}
126 ; CHECK-NEXT:   .long   0
127 define void @osrcold(i64 %a, i64 %b) {
128 entry:
129   %test = icmp slt i64 %a, %b
130   br i1 %test, label %ret, label %cold
131 cold:
132   ; OSR patchpoint with 12-byte nop-slide and 2 live vars.
133   %thunk = inttoptr i64 -559038737 to i8*
134   call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 4, i32 15, i8* %thunk, i32 0, i64 %a, i64 %b)
135   unreachable
136 ret:
137   ret void
138 }
139
140 ; Property Read
141 ; CHECK-LABEL:  .long   L{{.*}}-_propertyRead
142 ; CHECK-NEXT:   .short  0
143 ; CHECK-NEXT:   .short  2
144 ; CHECK-NEXT:   .byte   1
145 ; CHECK-NEXT:   .byte   8
146 ; CHECK-NEXT:   .short  {{[0-9]+}}
147 ; CHECK-NEXT:   .long   0
148 ; CHECK-NEXT:   .byte   1
149 ; CHECK-NEXT:   .byte   8
150 ; CHECK-NEXT:   .short  {{[0-9]+}}
151 ; CHECK-NEXT:   .long   0
152 define i64 @propertyRead(i64* %obj) {
153 entry:
154   %resolveRead = inttoptr i64 -559038737 to i8*
155   %result = call anyregcc i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 5, i32 15, i8* %resolveRead, i32 1, i64* %obj)
156   %add = add i64 %result, 3
157   ret i64 %add
158 }
159
160 ; Property Write
161 ; CHECK-LABEL:  .long   L{{.*}}-_propertyWrite
162 ; CHECK-NEXT:   .short  0
163 ; CHECK-NEXT:   .short  2
164 ; CHECK-NEXT:   .byte   1
165 ; CHECK-NEXT:   .byte   8
166 ; CHECK-NEXT:   .short  {{[0-9]+}}
167 ; CHECK-NEXT:   .long   0
168 ; CHECK-NEXT:   .byte   1
169 ; CHECK-NEXT:   .byte   8
170 ; CHECK-NEXT:   .short  {{[0-9]+}}
171 ; CHECK-NEXT:   .long   0
172 define void @propertyWrite(i64 %dummy1, i64* %obj, i64 %dummy2, i64 %a) {
173 entry:
174   %resolveWrite = inttoptr i64 -559038737 to i8*
175   call anyregcc void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 6, i32 15, i8* %resolveWrite, i32 2, i64* %obj, i64 %a)
176   ret void
177 }
178
179 ; Void JS Call
180 ;
181 ; 2 live variables in registers.
182 ;
183 ; CHECK-LABEL:  .long   L{{.*}}-_jsVoidCall
184 ; CHECK-NEXT:   .short  0
185 ; CHECK-NEXT:   .short  2
186 ; CHECK-NEXT:   .byte   1
187 ; CHECK-NEXT:   .byte   8
188 ; CHECK-NEXT:   .short  {{[0-9]+}}
189 ; CHECK-NEXT:   .long   0
190 ; CHECK-NEXT:   .byte   1
191 ; CHECK-NEXT:   .byte   8
192 ; CHECK-NEXT:   .short  {{[0-9]+}}
193 ; CHECK-NEXT:   .long   0
194 define void @jsVoidCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) {
195 entry:
196   %resolveCall = inttoptr i64 -559038737 to i8*
197   call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 7, i32 15, i8* %resolveCall, i32 2, i64* %obj, i64 %arg, i64 %l1, i64 %l2)
198   ret void
199 }
200
201 ; i64 JS Call
202 ;
203 ; 2 live variables in registers.
204 ;
205 ; CHECK-LABEL:  .long   L{{.*}}-_jsIntCall
206 ; CHECK-NEXT:   .short  0
207 ; CHECK-NEXT:   .short  2
208 ; CHECK-NEXT:   .byte   1
209 ; CHECK-NEXT:   .byte   8
210 ; CHECK-NEXT:   .short  {{[0-9]+}}
211 ; CHECK-NEXT:   .long   0
212 ; CHECK-NEXT:   .byte   1
213 ; CHECK-NEXT:   .byte   8
214 ; CHECK-NEXT:   .short  {{[0-9]+}}
215 ; CHECK-NEXT:   .long   0
216 define i64 @jsIntCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) {
217 entry:
218   %resolveCall = inttoptr i64 -559038737 to i8*
219   %result = call i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 8, i32 15, i8* %resolveCall, i32 2, i64* %obj, i64 %arg, i64 %l1, i64 %l2)
220   %add = add i64 %result, 3
221   ret i64 %add
222 }
223
224 ; Spilled stack map values.
225 ;
226 ; Verify 17 stack map entries.
227 ;
228 ; CHECK-LABEL:  .long L{{.*}}-_spilledValue
229 ; CHECK-NEXT:   .short 0
230 ; CHECK-NEXT:   .short 17
231 ;
232 ; Check that at least one is a spilled entry from RBP.
233 ; Location: Indirect RBP + ...
234 ; CHECK:        .byte 3
235 ; CHECK-NEXT:   .byte 8
236 ; CHECK-NEXT:   .short 6
237 define void @spilledValue(i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16) {
238 entry:
239   call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 11, i32 15, i8* null, i32 5, i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16)
240   ret void
241 }
242
243 ; Spilled stack map values.
244 ;
245 ; Verify 17 stack map entries.
246 ;
247 ; CHECK-LABEL:  .long L{{.*}}-_spilledStackMapValue
248 ; CHECK-NEXT:   .short 0
249 ; CHECK-NEXT:   .short 17
250 ;
251 ; Check that at least one is a spilled entry from RBP.
252 ; Location: Indirect RBP + ...
253 ; CHECK:        .byte 3
254 ; CHECK-NEXT:   .byte 8
255 ; CHECK-NEXT:   .short 6
256 define webkit_jscc void @spilledStackMapValue(i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16) {
257 entry:
258   call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 12, i32 15, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16)
259   ret void
260 }
261
262 ; Spill a subregister stackmap operand.
263 ;
264 ; CHECK-LABEL:  .long L{{.*}}-_spillSubReg
265 ; CHECK-NEXT:   .short 0
266 ; 4 locations
267 ; CHECK-NEXT:   .short 1
268 ;
269 ; Check that the subregister operand is a 4-byte spill.
270 ; Location: Indirect, 4-byte, RBP + ...
271 ; CHECK:        .byte 3
272 ; CHECK-NEXT:   .byte 4
273 ; CHECK-NEXT:   .short 6
274 define void @spillSubReg(i64 %arg) #0 {
275 bb:
276   br i1 undef, label %bb1, label %bb2
277
278 bb1:
279   unreachable
280
281 bb2:
282   %tmp = load i64* inttoptr (i64 140685446136880 to i64*)
283   br i1 undef, label %bb16, label %bb17
284
285 bb16:
286   unreachable
287
288 bb17:
289   %tmp32 = trunc i64 %tmp to i32
290   br i1 undef, label %bb60, label %bb61
291
292 bb60:
293   tail call void asm sideeffect "nop", "~{ax},~{bx},~{cx},~{dx},~{bp},~{si},~{di},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"() nounwind
294   tail call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 13, i32 5, i32 %tmp32)
295   unreachable
296
297 bb61:
298   unreachable
299 }
300
301 ; Map a single byte subregister. There is no DWARF register number, so
302 ; we expect the register to be encoded with the proper size and spill offset. We don't know which
303 ;
304 ; CHECK-LABEL:  .long L{{.*}}-_subRegOffset
305 ; CHECK-NEXT:   .short 0
306 ; 2 locations
307 ; CHECK-NEXT:   .short 2
308 ;
309 ; Check that the subregister operands are 1-byte spills.
310 ; Location 0: Register, 4-byte, AL
311 ; CHECK-NEXT:   .byte 1
312 ; CHECK-NEXT:   .byte 1
313 ; CHECK-NEXT:   .short 0
314 ; CHECK-NEXT:   .long 0
315 ;
316 ; Location 1: Register, 4-byte, BL
317 ; CHECK-NEXT:   .byte 1
318 ; CHECK-NEXT:   .byte 1
319 ; CHECK-NEXT:   .short 3
320 ; CHECK-NEXT:   .long 0
321 define void @subRegOffset(i16 %arg) {
322   %v = mul i16 %arg, 5
323   %a0 = trunc i16 %v to i8
324   tail call void asm sideeffect "nop", "~{bx}"() nounwind
325   %arghi = lshr i16 %v, 8
326   %a1 = trunc i16 %arghi to i8
327   tail call void asm sideeffect "nop", "~{cx},~{dx},~{bp},~{si},~{di},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"() nounwind
328   tail call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 14, i32 5, i8 %a0, i8 %a1)
329   ret void
330 }
331
332 ; Map a constant value.
333 ;
334 ; CHECK-LABEL:  .long L{{.*}}-_liveConstant
335 ; CHECK-NEXT:   .short 0
336 ; 1 location
337 ; CHECK-NEXT:   .short 1
338 ; Loc 0: SmallConstant
339 ; CHECK-NEXT:   .byte   4
340 ; CHECK-NEXT:   .byte   8
341 ; CHECK-NEXT:   .short  0
342 ; CHECK-NEXT:   .long   33
343
344 define void @liveConstant() {
345   tail call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 15, i32 5, i32 33)
346   ret void
347 }
348
349 ; Directly map an alloca's address.
350 ;
351 ; Callsite 16
352 ; CHECK-LABEL:  .long L{{.*}}-_directFrameIdx
353 ; CHECK-NEXT:   .short 0
354 ; 1 location
355 ; CHECK-NEXT:   .short  1
356 ; Loc 0: Direct RBP - ofs
357 ; CHECK-NEXT:   .byte   2
358 ; CHECK-NEXT:   .byte   8
359 ; CHECK-NEXT:   .short  6
360 ; CHECK-NEXT:   .long
361
362 ; Callsite 17
363 ; CHECK-LABEL:  .long   L{{.*}}-_directFrameIdx
364 ; CHECK-NEXT:   .short  0
365 ; 2 locations
366 ; CHECK-NEXT:   .short  2
367 ; Loc 0: Direct RBP - ofs
368 ; CHECK-NEXT:   .byte   2
369 ; CHECK-NEXT:   .byte   8
370 ; CHECK-NEXT:   .short  6
371 ; CHECK-NEXT:   .long
372 ; Loc 1: Direct RBP - ofs
373 ; CHECK-NEXT:   .byte   2
374 ; CHECK-NEXT:   .byte   8
375 ; CHECK-NEXT:   .short  6
376 ; CHECK-NEXT:   .long
377 define void @directFrameIdx() {
378 entry:
379   %metadata1 = alloca i64, i32 3, align 8
380   store i64 11, i64* %metadata1
381   store i64 12, i64* %metadata1
382   store i64 13, i64* %metadata1
383   call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 16, i32 0, i64* %metadata1)
384   %metadata2 = alloca i8, i32 4, align 8
385   %metadata3 = alloca i16, i32 4, align 8
386   call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 17, i32 5, i8* null, i32 0, i8* %metadata2, i16* %metadata3)
387   ret void
388 }
389
390 ; Test a 64-bit ID.
391 ;
392 ; CHECK:        .quad 4294967295
393 ; CHECK-LABEL:  .long L{{.*}}-_longid
394 ; CHECK:        .quad 4294967296
395 ; CHECK-LABEL:  .long L{{.*}}-_longid
396 ; CHECK:        .quad 9223372036854775807
397 ; CHECK-LABEL:  .long L{{.*}}-_longid
398 ; CHECK:        .quad -1
399 ; CHECK-LABEL:  .long L{{.*}}-_longid
400 define void @longid() {
401 entry:
402   tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 4294967295, i32 0, i8* null, i32 0)
403   tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 4294967296, i32 0, i8* null, i32 0)
404   tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 9223372036854775807, i32 0, i8* null, i32 0)
405   tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 -1, i32 0, i8* null, i32 0)
406   ret void
407 }
408
409 declare void @llvm.experimental.stackmap(i64, i32, ...)
410 declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...)
411 declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...)