1 ; RUN: llc < %s | FileCheck %s 2 ; 3 ; Note: Print verbose stackmaps using -debug-only=stackmaps. 4 5 ; We are not getting the correct stack alignment when cross compiling for arm64. 6 ; So specify a datalayout here. 7 target datalayout = "E-m:e-i64:64-n32:64" 8 target triple = "powerpc64-unknown-linux-gnu" 9 10 ; CHECK-LABEL: constantargs: 11 ; CHECK: {{^}}.L[[constantargs_BEGIN:.*]]:{{$}} 12 13 ; CHECK-LABEL: osrinline: 14 ; CHECK: {{^}}.L[[osrinline_BEGIN:.*]]:{{$}} 15 16 ; CHECK-LABEL: osrcold: 17 ; CHECK: {{^}}.L[[osrcold_BEGIN:.*]]:{{$}} 18 19 ; CHECK-LABEL: propertyRead: 20 ; CHECK: {{^}}.L[[propertyRead_BEGIN:.*]]:{{$}} 21 22 ; CHECK-LABEL: propertyWrite: 23 ; CHECK: {{^}}.L[[propertyWrite_BEGIN:.*]]:{{$}} 24 25 ; CHECK-LABEL: jsVoidCall: 26 ; CHECK: {{^}}.L[[jsVoidCall_BEGIN:.*]]:{{$}} 27 28 ; CHECK-LABEL: jsIntCall: 29 ; CHECK: {{^}}.L[[jsIntCall_BEGIN:.*]]:{{$}} 30 31 ; CHECK-LABEL: spilledValue: 32 ; CHECK: {{^}}.L[[spilledValue_BEGIN:.*]]:{{$}} 33 34 ; CHECK-LABEL: spilledStackMapValue: 35 ; CHECK: {{^}}.L[[spilledStackMapValue_BEGIN:.*]]:{{$}} 36 37 ; CHECK-LABEL: liveConstant: 38 ; CHECK: {{^}}.L[[liveConstant_BEGIN:.*]]:{{$}} 39 40 ; CHECK-LABEL: clobberLR: 41 ; CHECK: {{^}}.L[[clobberLR_BEGIN:.*]]:{{$}} 42 43 44 ; CHECK-LABEL: .section .llvm_stackmaps 45 ; CHECK-NEXT: __LLVM_StackMaps: 46 ; Header 47 ; CHECK-NEXT: .byte 3 48 ; CHECK-NEXT: .byte 0 49 ; CHECK-NEXT: .short 0 50 ; Num Functions 51 ; CHECK-NEXT: .long 11 52 ; Num LargeConstants 53 ; CHECK-NEXT: .long 2 54 ; Num Callsites 55 ; CHECK-NEXT: .long 11 56 57 ; Functions and stack size 58 ; CHECK-NEXT: .quad constantargs 59 ; CHECK-NEXT: .quad 128 60 ; CHECK-NEXT: .quad 1 61 ; CHECK-NEXT: .quad osrinline 62 ; CHECK-NEXT: .quad 144 63 ; CHECK-NEXT: .quad 1 64 ; CHECK-NEXT: .quad osrcold 65 ; CHECK-NEXT: .quad 128 66 ; CHECK-NEXT: .quad 1 67 ; CHECK-NEXT: .quad propertyRead 68 ; CHECK-NEXT: .quad 128 69 ; CHECK-NEXT: .quad 1 70 ; CHECK-NEXT: .quad propertyWrite 71 ; CHECK-NEXT: .quad 128 72 ; CHECK-NEXT: .quad 1 73 ; CHECK-NEXT: .quad jsVoidCall 74 ; CHECK-NEXT: .quad 128 75 ; CHECK-NEXT: .quad 1 76 ; CHECK-NEXT: .quad jsIntCall 77 ; CHECK-NEXT: .quad 128 78 ; CHECK-NEXT: .quad 1 79 ; CHECK-NEXT: .quad spilledValue 80 ; CHECK-NEXT: .quad 304 81 ; CHECK-NEXT: .quad 1 82 ; CHECK-NEXT: .quad spilledStackMapValue 83 ; CHECK-NEXT: .quad 224 84 ; CHECK-NEXT: .quad 1 85 ; CHECK-NEXT: .quad liveConstant 86 ; CHECK-NEXT: .quad 64 87 ; CHECK-NEXT: .quad 1 88 ; CHECK-NEXT: .quad clobberLR 89 ; CHECK-NEXT: .quad 208 90 ; CHECK-NEXT: .quad 1 91 92 ; Num LargeConstants 93 ; CHECK-NEXT: .quad 4294967295 94 ; CHECK-NEXT: .quad 4294967296 95 96 ; Constant arguments 97 ; 98 ; CHECK-NEXT: .quad 1 99 ; CHECK-NEXT: .long .L{{.*}}-.L[[constantargs_BEGIN]] 100 ; CHECK-NEXT: .short 0 101 ; CHECK-NEXT: .short 4 102 ; SmallConstant 103 ; CHECK-NEXT: .byte 4 104 ; CHECK-NEXT: .byte 0 105 ; CHECK-NEXT: .short 8 106 ; CHECK-NEXT: .short 0 107 ; CHECK-NEXT: .short 0 108 ; CHECK-NEXT: .long 65535 109 ; SmallConstant 110 ; CHECK-NEXT: .byte 4 111 ; CHECK-NEXT: .byte 0 112 ; CHECK-NEXT: .short 8 113 ; CHECK-NEXT: .short 0 114 ; CHECK-NEXT: .short 0 115 ; CHECK-NEXT: .long 65536 116 ; SmallConstant 117 ; CHECK-NEXT: .byte 5 118 ; CHECK-NEXT: .byte 0 119 ; CHECK-NEXT: .short 8 120 ; CHECK-NEXT: .short 0 121 ; CHECK-NEXT: .short 0 122 ; CHECK-NEXT: .long 0 123 ; LargeConstant at index 0 124 ; CHECK-NEXT: .byte 5 125 ; CHECK-NEXT: .byte 0 126 ; CHECK-NEXT: .short 8 127 ; CHECK-NEXT: .short 0 128 ; CHECK-NEXT: .short 0 129 ; CHECK-NEXT: .long 1 130 131 define void @constantargs() { 132 entry: 133 %0 = inttoptr i64 244837814094590 to i8* 134 tail call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 1, i32 40, i8* %0, i32 0, i64 65535, i64 65536, i64 4294967295, i64 4294967296) 135 ret void 136 } 137 138 ; Inline OSR Exit 139 ; 140 ; CHECK: .long .L{{.*}}-.L[[osrinline_BEGIN]] 141 ; CHECK-NEXT: .short 0 142 ; CHECK-NEXT: .short 2 143 ; CHECK-NEXT: .byte 1 144 ; CHECK-NEXT: .byte 0 145 ; CHECK-NEXT: .short 8 146 ; CHECK-NEXT: .short {{[0-9]+}} 147 ; CHECK-NEXT: .short 0 148 ; CHECK-NEXT: .long 0 149 ; CHECK-NEXT: .byte 1 150 ; CHECK-NEXT: .byte 0 151 ; CHECK-NEXT: .short 8 152 ; CHECK-NEXT: .short {{[0-9]+}} 153 ; CHECK-NEXT: .short 0 154 ; CHECK-NEXT: .long 0 155 define void @osrinline(i64 %a, i64 %b) { 156 entry: 157 ; Runtime void->void call. 158 call void inttoptr (i64 244837814094590 to void ()*)() 159 ; Followed by inline OSR patchpoint with 12-byte shadow and 2 live vars. 160 call void (i64, i32, ...) @llvm.experimental.stackmap(i64 3, i32 12, i64 %a, i64 %b) 161 ret void 162 } 163 164 ; Cold OSR Exit 165 ; 166 ; 2 live variables in register. 167 ; 168 ; CHECK: .long .L{{.*}}-.L[[osrcold_BEGIN]] 169 ; CHECK-NEXT: .short 0 170 ; CHECK-NEXT: .short 2 171 ; CHECK-NEXT: .byte 1 172 ; CHECK-NEXT: .byte 0 173 ; CHECK-NEXT: .short 8 174 ; CHECK-NEXT: .short {{[0-9]+}} 175 ; CHECK-NEXT: .short 0 176 ; CHECK-NEXT: .long 0 177 ; CHECK-NEXT: .byte 1 178 ; CHECK-NEXT: .byte 0 179 ; CHECK-NEXT: .short 8 180 ; CHECK-NEXT: .short {{[0-9]+}} 181 ; CHECK-NEXT: .short 0 182 ; CHECK-NEXT: .long 0 183 define void @osrcold(i64 %a, i64 %b) { 184 entry: 185 %test = icmp slt i64 %a, %b 186 br i1 %test, label %ret, label %cold 187 cold: 188 ; OSR patchpoint with 12-byte nop-slide and 2 live vars. 189 %thunk = inttoptr i64 244837814094590 to i8* 190 call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 4, i32 40, i8* %thunk, i32 0, i64 %a, i64 %b) 191 unreachable 192 ret: 193 ret void 194 } 195 196 ; Property Read 197 ; CHECK: .long .L{{.*}}-.L[[propertyRead_BEGIN]] 198 ; CHECK-NEXT: .short 0 199 ; CHECK-NEXT: .short 0 200 ; 201 ; FIXME: There are currently no stackmap entries. After moving to 202 ; AnyRegCC, we will have entries for the object and return value. 203 define i64 @propertyRead(i64* %obj) { 204 entry: 205 %resolveRead = inttoptr i64 244837814094590 to i8* 206 %result = call i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 5, i32 40, i8* %resolveRead, i32 1, i64* %obj) 207 %add = add i64 %result, 3 208 ret i64 %add 209 } 210 211 ; Property Write 212 ; CHECK: .long .L{{.*}}-.L[[propertyWrite_BEGIN]] 213 ; CHECK-NEXT: .short 0 214 ; CHECK-NEXT: .short 2 215 ; CHECK-NEXT: .byte 1 216 ; CHECK-NEXT: .byte 0 217 ; CHECK-NEXT: .short 8 218 ; CHECK-NEXT: .short {{[0-9]+}} 219 ; CHECK-NEXT: .short 0 220 ; CHECK-NEXT: .long 0 221 ; CHECK-NEXT: .byte 1 222 ; CHECK-NEXT: .byte 0 223 ; CHECK-NEXT: .short 8 224 ; CHECK-NEXT: .short {{[0-9]+}} 225 ; CHECK-NEXT: .short 0 226 ; CHECK-NEXT: .long 0 227 define void @propertyWrite(i64 %dummy1, i64* %obj, i64 %dummy2, i64 %a) { 228 entry: 229 %resolveWrite = inttoptr i64 244837814094590 to i8* 230 call anyregcc void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 6, i32 40, i8* %resolveWrite, i32 2, i64* %obj, i64 %a) 231 ret void 232 } 233 234 ; Void JS Call 235 ; 236 ; 2 live variables in registers. 237 ; 238 ; CHECK: .long .L{{.*}}-.L[[jsVoidCall_BEGIN]] 239 ; CHECK-NEXT: .short 0 240 ; CHECK-NEXT: .short 2 241 ; CHECK-NEXT: .byte 1 242 ; CHECK-NEXT: .byte 0 243 ; CHECK-NEXT: .short 8 244 ; CHECK-NEXT: .short {{[0-9]+}} 245 ; CHECK-NEXT: .short 0 246 ; CHECK-NEXT: .long 0 247 ; CHECK-NEXT: .byte 1 248 ; CHECK-NEXT: .byte 0 249 ; CHECK-NEXT: .short 8 250 ; CHECK-NEXT: .short {{[0-9]+}} 251 ; CHECK-NEXT: .short 0 252 ; CHECK-NEXT: .long 0 253 define void @jsVoidCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) { 254 entry: 255 %resolveCall = inttoptr i64 244837814094590 to i8* 256 call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 7, i32 40, i8* %resolveCall, i32 2, i64* %obj, i64 %arg, i64 %l1, i64 %l2) 257 ret void 258 } 259 260 ; i64 JS Call 261 ; 262 ; 2 live variables in registers. 263 ; 264 ; CHECK: .long .L{{.*}}-.L[[jsIntCall_BEGIN]] 265 ; CHECK-NEXT: .short 0 266 ; CHECK-NEXT: .short 2 267 ; CHECK-NEXT: .byte 1 268 ; CHECK-NEXT: .byte 0 269 ; CHECK-NEXT: .short 8 270 ; CHECK-NEXT: .short {{[0-9]+}} 271 ; CHECK-NEXT: .short 0 272 ; CHECK-NEXT: .long 0 273 ; CHECK-NEXT: .byte 1 274 ; CHECK-NEXT: .byte 0 275 ; CHECK-NEXT: .short 8 276 ; CHECK-NEXT: .short {{[0-9]+}} 277 ; CHECK-NEXT: .short 0 278 ; CHECK-NEXT: .long 0 279 define i64 @jsIntCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) { 280 entry: 281 %resolveCall = inttoptr i64 244837814094590 to i8* 282 %result = call i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 8, i32 40, i8* %resolveCall, i32 2, i64* %obj, i64 %arg, i64 %l1, i64 %l2) 283 %add = add i64 %result, 3 284 ret i64 %add 285 } 286 287 ; Spilled stack map values. 288 ; 289 ; Verify 28 stack map entries. 290 ; 291 ; CHECK: .long .L{{.*}}-.L[[spilledValue_BEGIN]] 292 ; CHECK-NEXT: .short 0 293 ; CHECK-NEXT: .short 28 294 ; 295 ; Check that at least one is a spilled entry from r31. 296 ; Location: Indirect FP + ... 297 ; CHECK: .byte 3 298 ; CHECK-NEXT: .byte 0 299 ; CHECK-NEXT: .short 300 ; CHECK-NEXT: .short 31 301 ; CHECK-NEXT: .short 0 302 ; CHECK-NEXT: .long 303 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, i64 %l17, i64 %l18, i64 %l19, i64 %l20, i64 %l21, i64 %l22, i64 %l23, i64 %l24, i64 %l25, i64 %l26, i64 %l27) { 304 entry: 305 call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 11, i32 40, 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, i64 %l17, i64 %l18, i64 %l19, i64 %l20, i64 %l21, i64 %l22, i64 %l23, i64 %l24, i64 %l25, i64 %l26, i64 %l27) 306 ret void 307 } 308 309 ; Spilled stack map values. 310 ; 311 ; Verify 30 stack map entries. 312 ; 313 ; CHECK: .long .L{{.*}}-.L[[spilledStackMapValue_BEGIN]] 314 ; CHECK-NEXT: .short 0 315 ; CHECK-NEXT: .short 30 316 ; 317 ; Check that at least one is a spilled entry from r31. 318 ; Location: Indirect FP + ... 319 ; CHECK: .byte 3 320 ; CHECK-NEXT: .byte 0 321 ; CHECK-NEXT: .short 322 ; CHECK-NEXT: .short 31 323 ; CHECK-NEXT: .short 0 324 ; CHECK-NEXT: .long 325 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, i64 %l17, i64 %l18, i64 %l19, i64 %l20, i64 %l21, i64 %l22, i64 %l23, i64 %l24, i64 %l25, i64 %l26, i64 %l27, i64 %l28, i64 %l29) { 326 entry: 327 call void (i64, i32, ...) @llvm.experimental.stackmap(i64 12, i32 16, 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, i64 %l17, i64 %l18, i64 %l19, i64 %l20, i64 %l21, i64 %l22, i64 %l23, i64 %l24, i64 %l25, i64 %l26, i64 %l27, i64 %l28, i64 %l29) 328 ret void 329 } 330 331 332 ; Map a constant value. 333 ; 334 ; CHECK: .long .L{{.*}}-.L[[liveConstant_BEGIN]] 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 0 341 ; CHECK-NEXT: .short 8 342 ; CHECK-NEXT: .short 0 343 ; CHECK-NEXT: .short 0 344 ; CHECK-NEXT: .long 33 345 346 define void @liveConstant() { 347 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 15, i32 8, i32 33) 348 ret void 349 } 350 351 ; Map a value when LR is the only free register. 352 ; 353 ; CHECK: .long .L{{.*}}-.L[[clobberLR_BEGIN]] 354 ; CHECK-NEXT: .short 0 355 ; 1 location 356 ; CHECK-NEXT: .short 1 357 ; Loc 0: Indirect FP (r31) - offset 358 ; CHECK-NEXT: .byte 3 359 ; CHECK-NEXT: .byte 0 360 ; CHECK-NEXT: .short 4 361 ; CHECK-NEXT: .short 31 362 ; CHECK-NEXT: .short 0 363 ; CHECK-NEXT: .long {{[0-9]+}} 364 define void @clobberLR(i32 %a) { 365 tail call void asm sideeffect "nop", "~{r0},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{r14},~{r15},~{r16},~{r17},~{r18},~{r19},~{r20},~{r21},~{r22},~{r23},~{r24},~{r25},~{r26},~{r27},~{r28},~{r29},~{r30},~{r31}"() nounwind 366 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 16, i32 8, i32 %a) 367 ret void 368 } 369 370 declare void @llvm.experimental.stackmap(i64, i32, ...) 371 declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...) 372 declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...) 373