1 ; RUN: llc < %s -verify-machineinstrs -stack-symbol-ordering=0 -mtriple="x86_64-pc-linux-gnu" | FileCheck %s 2 ; RUN: llc < %s -verify-machineinstrs -stack-symbol-ordering=0 -mtriple="x86_64-pc-unknown-elf" | FileCheck %s 3 4 ; This test is a sanity check to ensure statepoints are generating StackMap 5 ; sections correctly. This is not intended to be a rigorous test of the 6 ; StackMap format (see the stackmap tests for that). 7 8 target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128" 9 10 declare zeroext i1 @return_i1() 11 12 define i1 @test(i32 addrspace(1)* %ptr_base, i32 %arg) 13 gc "statepoint-example" { 14 ; CHECK-LABEL: test: 15 ; Do we see two spills for the local values and the store to the 16 ; alloca? 17 ; CHECK: subq $40, %rsp 18 ; CHECK: movq $0, 24(%rsp) 19 ; CHECK: movq %rdi, 16(%rsp) 20 ; CHECK: movq %rax, 8(%rsp) 21 ; CHECK: callq return_i1 22 ; CHECK: addq $40, %rsp 23 ; CHECK: retq 24 entry: 25 %metadata1 = alloca i32 addrspace(1)*, i32 2, align 8 26 store i32 addrspace(1)* null, i32 addrspace(1)** %metadata1 27 %ptr_derived = getelementptr i32, i32 addrspace(1)* %ptr_base, i32 %arg 28 %safepoint_token = tail call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 2, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* null, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* %ptr_derived, i32 addrspace(1)* null) 29 %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token) 30 %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token, i32 9, i32 9) 31 %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token, i32 9, i32 10) 32 %c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token, i32 11, i32 11) 33 ; 34 ret i1 %call1 35 } 36 37 ; This is similar to the previous test except that we have derived pointer as 38 ; argument to the function. Despite that this can not happen after the 39 ; RewriteSafepointForGC pass, lowering should be able to handle it anyway. 40 define i1 @test_derived_arg(i32 addrspace(1)* %ptr_base, 41 i32 addrspace(1)* %ptr_derived) 42 gc "statepoint-example" { 43 ; CHECK-LABEL: test_derived_arg 44 ; Do we see two spills for the local values and the store to the 45 ; alloca? 46 ; CHECK: subq $40, %rsp 47 ; CHECK: movq $0, 24(%rsp) 48 ; CHECK: movq %rdi, 16(%rsp) 49 ; CHECK: movq %rsi, 8(%rsp) 50 ; CHECK: callq return_i1 51 ; CHECK: addq $40, %rsp 52 ; CHECK: retq 53 entry: 54 %metadata1 = alloca i32 addrspace(1)*, i32 2, align 8 55 store i32 addrspace(1)* null, i32 addrspace(1)** %metadata1 56 %safepoint_token = tail call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 2, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* null, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* %ptr_derived, i32 addrspace(1)* null) 57 %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token) 58 %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token, i32 9, i32 9) 59 %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token, i32 9, i32 10) 60 %c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token, i32 11, i32 11) 61 ; 62 ret i1 %call1 63 } 64 65 ; Simple test case to check that we emit the ID field correctly 66 define i1 @test_id() gc "statepoint-example" { 67 ; CHECK-LABEL: test_id 68 entry: 69 %safepoint_token = tail call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 237, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) 70 %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token) 71 ret i1 %call1 72 } 73 74 75 declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...) 76 declare i1 @llvm.experimental.gc.result.i1(token) 77 declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32) #3 78 79 ; CHECK-LABEL: .section .llvm_stackmaps 80 ; CHECK-NEXT: __LLVM_StackMaps: 81 ; Header 82 ; CHECK-NEXT: .byte 3 83 ; CHECK-NEXT: .byte 0 84 ; CHECK-NEXT: .short 0 85 ; Num Functions 86 ; CHECK-NEXT: .long 3 87 ; Num LargeConstants 88 ; CHECK-NEXT: .long 0 89 ; Num Callsites 90 ; CHECK-NEXT: .long 3 91 92 ; Functions and stack size 93 ; CHECK-NEXT: .quad test 94 ; CHECK-NEXT: .quad 40 95 ; CHECK-NEXT: .quad 1 96 ; CHECK-NEXT: .quad test_derived_arg 97 ; CHECK-NEXT: .quad 40 98 ; CHECK-NEXT: .quad 1 99 ; CHECK-NEXT: .quad test_id 100 ; CHECK-NEXT: .quad 8 101 ; CHECK-NEXT: .quad 1 102 103 ; 104 ; test 105 ; 106 107 ; Statepoint ID 108 ; CHECK-NEXT: .quad 0 109 110 ; Callsites 111 ; Constant arguments 112 ; CHECK-NEXT: .long .Ltmp0-test 113 ; CHECK: .short 0 114 ; CHECK: .short 11 115 ; SmallConstant (0) 116 ; CHECK: .byte 4 117 ; CHECK-NEXT: .byte 0 118 ; CHECK: .short 8 119 ; CHECK: .short 0 120 ; CHECK-NEXT: .short 0 121 ; CHECK: .long 0 122 ; SmallConstant (0) 123 ; CHECK: .byte 4 124 ; CHECK-NEXT: .byte 0 125 ; CHECK: .short 8 126 ; CHECK: .short 0 127 ; CHECK-NEXT: .short 0 128 ; CHECK: .long 0 129 ; SmallConstant (2) 130 ; CHECK: .byte 4 131 ; CHECK-NEXT: .byte 0 132 ; CHECK: .short 8 133 ; CHECK: .short 0 134 ; CHECK-NEXT: .short 0 135 ; CHECK: .long 2 136 ; Indirect Spill Slot [RSP+0] 137 ; CHECK: .byte 3 138 ; CHECK-NEXT: .byte 0 139 ; CHECK: .short 8 140 ; CHECK: .short 7 141 ; CHECK-NEXT: .short 0 142 ; CHECK: .long 16 143 ; SmallConstant (0) 144 ; CHECK: .byte 4 145 ; CHECK-NEXT: .byte 0 146 ; CHECK: .short 8 147 ; CHECK: .short 0 148 ; CHECK-NEXT: .short 0 149 ; CHECK: .long 0 150 ; SmallConstant (0) 151 ; CHECK: .byte 4 152 ; CHECK-NEXT: .byte 0 153 ; CHECK: .short 8 154 ; CHECK: .short 0 155 ; CHECK-NEXT: .short 0 156 ; CHECK: .long 0 157 ; SmallConstant (0) 158 ; CHECK: .byte 4 159 ; CHECK-NEXT: .byte 0 160 ; CHECK: .short 8 161 ; CHECK: .short 0 162 ; CHECK-NEXT: .short 0 163 ; CHECK: .long 0 164 ; Indirect Spill Slot [RSP+16] 165 ; CHECK: .byte 3 166 ; CHECK-NEXT: .byte 0 167 ; CHECK: .short 8 168 ; CHECK: .short 7 169 ; CHECK-NEXT: .short 0 170 ; CHECK: .long 16 171 ; Indirect Spill Slot [RSP+8] 172 ; CHECK: .byte 3 173 ; CHECK-NEXT: .byte 0 174 ; CHECK: .short 8 175 ; CHECK: .short 7 176 ; CHECK-NEXT: .short 0 177 ; CHECK: .long 8 178 ; Indirect Spill Slot [RSP+16] 179 ; CHECK: .byte 3 180 ; CHECK-NEXT: .byte 0 181 ; CHECK: .short 8 182 ; CHECK: .short 7 183 ; CHECK-NEXT: .short 0 184 ; CHECK: .long 16 185 ; Indirect Spill Slot [RSP+16] 186 ; CHECK: .byte 3 187 ; CHECK-NEXT: .byte 0 188 ; CHECK: .short 8 189 ; CHECK: .short 7 190 ; CHECK-NEXT: .short 0 191 ; CHECK: .long 16 192 193 ; No Padding or LiveOuts 194 ; CHECK: .short 0 195 ; CHECK: .short 0 196 ; CHECK: .p2align 3 197 198 ; 199 ; test_derived_arg 200 201 ; Statepoint ID 202 ; CHECK-NEXT: .quad 0 203 204 ; Callsites 205 ; Constant arguments 206 ; CHECK-NEXT: .long .Ltmp1-test_derived_arg 207 ; CHECK: .short 0 208 ; CHECK: .short 11 209 ; SmallConstant (0) 210 ; CHECK: .byte 4 211 ; CHECK-NEXT: .byte 0 212 ; CHECK: .short 8 213 ; CHECK: .short 0 214 ; CHECK-NEXT: .short 0 215 ; CHECK: .long 0 216 ; SmallConstant (2) 217 ; CHECK: .byte 4 218 ; CHECK-NEXT: .byte 0 219 ; CHECK: .short 8 220 ; CHECK: .short 0 221 ; CHECK-NEXT: .short 0 222 ; CHECK: .long 2 223 ; Indirect Spill Slot [RSP+0] 224 ; CHECK: .byte 3 225 ; CHECK-NEXT: .byte 0 226 ; CHECK: .short 8 227 ; CHECK: .short 7 228 ; CHECK-NEXT: .short 0 229 ; CHECK: .long 16 230 ; SmallConstant (0) 231 ; CHECK: .byte 4 232 ; CHECK-NEXT: .byte 0 233 ; CHECK: .short 8 234 ; CHECK: .short 0 235 ; CHECK-NEXT: .short 0 236 ; CHECK: .long 0 237 ; SmallConstant (0) 238 ; CHECK: .byte 4 239 ; CHECK-NEXT: .byte 0 240 ; CHECK: .short 8 241 ; CHECK: .short 0 242 ; CHECK-NEXT: .short 0 243 ; CHECK: .long 0 244 ; SmallConstant (0) 245 ; CHECK: .byte 4 246 ; CHECK-NEXT: .byte 0 247 ; CHECK: .short 8 248 ; CHECK: .short 0 249 ; CHECK-NEXT: .short 0 250 ; CHECK: .long 0 251 ; Indirect Spill Slot [RSP+16] 252 ; CHECK: .byte 3 253 ; CHECK-NEXT: .byte 0 254 ; CHECK: .short 8 255 ; CHECK: .short 7 256 ; CHECK-NEXT: .short 0 257 ; CHECK: .long 16 258 ; Indirect Spill Slot [RSP+8] 259 ; CHECK: .byte 3 260 ; CHECK-NEXT: .byte 0 261 ; CHECK: .short 8 262 ; CHECK: .short 7 263 ; CHECK-NEXT: .short 0 264 ; CHECK: .long 8 265 ; Indirect Spill Slot [RSP+16] 266 ; CHECK: .byte 3 267 ; CHECK-NEXT: .byte 0 268 ; CHECK: .short 8 269 ; CHECK: .short 7 270 ; CHECK-NEXT: .short 0 271 ; CHECK: .long 16 272 ; Indirect Spill Slot [RSP+16] 273 ; CHECK: .byte 3 274 ; CHECK-NEXT: .byte 0 275 ; CHECK: .short 8 276 ; CHECK: .short 7 277 ; CHECK-NEXT: .short 0 278 ; CHECK: .long 16 279 280 ; No Padding or LiveOuts 281 ; CHECK: .short 0 282 ; CHECK: .short 0 283 ; CHECK: .p2align 3 284 285 ; Records for the test_id function: 286 287 ; The Statepoint ID: 288 ; CHECK-NEXT: .quad 237 289 290 ; Instruction Offset 291 ; CHECK-NEXT: .long .Ltmp2-test_id 292 293 ; Reserved: 294 ; CHECK: .short 0 295 296 ; NumLocations: 297 ; CHECK: .short 3 298 299 ; StkMapRecord[0]: 300 ; SmallConstant(0): 301 ; CHECK: .byte 4 302 ; CHECK-NEXT: .byte 0 303 ; CHECK: .short 8 304 ; CHECK: .short 0 305 ; CHECK-NEXT: .short 0 306 ; CHECK: .long 0 307 308 ; StkMapRecord[1]: 309 ; SmallConstant(0): 310 ; CHECK: .byte 4 311 ; CHECK-NEXT: .byte 0 312 ; CHECK: .short 8 313 ; CHECK: .short 0 314 ; CHECK-NEXT: .short 0 315 ; CHECK: .long 0 316 317 ; StkMapRecord[2]: 318 ; SmallConstant(0): 319 ; CHECK: .byte 4 320 ; CHECK-NEXT: .byte 0 321 ; CHECK: .short 8 322 ; CHECK: .short 0 323 ; CHECK-NEXT: .short 0 324 ; CHECK: .long 0 325 326 ; No padding or LiveOuts 327 ; CHECK: .short 0 328 ; CHECK: .short 0 329 ; CHECK: .p2align 3 330