1 ; RUN: llc < %s -mtriple="x86_64-pc-linux-gnu" | FileCheck %s 2 ; RUN: llc < %s -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 i32 (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(i32 %safepoint_token) 30 %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 9) 31 %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 10) 32 %c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %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 i32 (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(i32 %safepoint_token) 58 %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 9) 59 %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 10) 60 %c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %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 i32 (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(i32 %safepoint_token) 71 ret i1 %call1 72 } 73 74 75 declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...) 76 declare i1 @llvm.experimental.gc.result.i1(i32) 77 declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3 78 79 ; CHECK-LABEL: .section .llvm_stackmaps 80 ; CHECK-NEXT: __LLVM_StackMaps: 81 ; Header 82 ; CHECK-NEXT: .byte 1 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 test_derived_arg 96 ; CHECK-NEXT: .quad 40 97 98 ; 99 ; test 100 ; 101 102 ; Large Constants 103 ; Statepoint ID only 104 ; CHECK: .quad 0 105 106 ; Callsites 107 ; Constant arguments 108 ; CHECK: .long .Ltmp1-test 109 ; CHECK: .short 0 110 ; CHECK: .short 11 111 ; SmallConstant (0) 112 ; CHECK: .byte 4 113 ; CHECK: .byte 8 114 ; CHECK: .short 0 115 ; CHECK: .long 0 116 ; SmallConstant (0) 117 ; CHECK: .byte 4 118 ; CHECK: .byte 8 119 ; CHECK: .short 0 120 ; CHECK: .long 0 121 ; SmallConstant (2) 122 ; CHECK: .byte 4 123 ; CHECK: .byte 8 124 ; CHECK: .short 0 125 ; CHECK: .long 2 126 ; Direct Spill Slot [RSP+0] 127 ; CHECK: .byte 2 128 ; CHECK: .byte 8 129 ; CHECK: .short 7 130 ; CHECK: .long 16 131 ; SmallConstant (0) 132 ; CHECK: .byte 4 133 ; CHECK: .byte 8 134 ; CHECK: .short 0 135 ; CHECK: .long 0 136 ; SmallConstant (0) 137 ; CHECK: .byte 4 138 ; CHECK: .byte 8 139 ; CHECK: .short 0 140 ; CHECK: .long 0 141 ; SmallConstant (0) 142 ; CHECK: .byte 4 143 ; CHECK: .byte 8 144 ; CHECK: .short 0 145 ; CHECK: .long 0 146 ; Direct Spill Slot [RSP+16] 147 ; CHECK: .byte 2 148 ; CHECK: .byte 8 149 ; CHECK: .short 7 150 ; CHECK: .long 16 151 ; Direct Spill Slot [RSP+8] 152 ; CHECK: .byte 2 153 ; CHECK: .byte 8 154 ; CHECK: .short 7 155 ; CHECK: .long 8 156 ; Direct Spill Slot [RSP+16] 157 ; CHECK: .byte 2 158 ; CHECK: .byte 8 159 ; CHECK: .short 7 160 ; CHECK: .long 16 161 ; Direct Spill Slot [RSP+16] 162 ; CHECK: .byte 2 163 ; CHECK: .byte 8 164 ; CHECK: .short 7 165 ; CHECK: .long 16 166 167 ; No Padding or LiveOuts 168 ; CHECK: .short 0 169 ; CHECK: .short 0 170 ; CHECK: .align 8 171 172 ; 173 ; test_derived_arg 174 ; 175 176 ; Large Constants 177 ; Statepoint ID only 178 ; CHECK: .quad 0 179 180 ; Callsites 181 ; Constant arguments 182 ; CHECK: .long .Ltmp3-test_derived_arg 183 ; CHECK: .short 0 184 ; CHECK: .short 11 185 ; SmallConstant (0) 186 ; CHECK: .byte 4 187 ; CHECK: .byte 8 188 ; CHECK: .short 0 189 ; CHECK: .long 0 190 ; SmallConstant (2) 191 ; CHECK: .byte 4 192 ; CHECK: .byte 8 193 ; CHECK: .short 0 194 ; CHECK: .long 2 195 ; Direct Spill Slot [RSP+0] 196 ; CHECK: .byte 2 197 ; CHECK: .byte 8 198 ; CHECK: .short 7 199 ; CHECK: .long 16 200 ; SmallConstant (0) 201 ; CHECK: .byte 4 202 ; CHECK: .byte 8 203 ; CHECK: .short 0 204 ; CHECK: .long 0 205 ; SmallConstant (0) 206 ; CHECK: .byte 4 207 ; CHECK: .byte 8 208 ; CHECK: .short 0 209 ; CHECK: .long 0 210 ; SmallConstant (0) 211 ; CHECK: .byte 4 212 ; CHECK: .byte 8 213 ; CHECK: .short 0 214 ; CHECK: .long 0 215 ; Direct Spill Slot [RSP+16] 216 ; CHECK: .byte 2 217 ; CHECK: .byte 8 218 ; CHECK: .short 7 219 ; CHECK: .long 16 220 ; Direct Spill Slot [RSP+8] 221 ; CHECK: .byte 2 222 ; CHECK: .byte 8 223 ; CHECK: .short 7 224 ; CHECK: .long 8 225 ; Direct Spill Slot [RSP+16] 226 ; CHECK: .byte 2 227 ; CHECK: .byte 8 228 ; CHECK: .short 7 229 ; CHECK: .long 16 230 ; Direct Spill Slot [RSP+16] 231 ; CHECK: .byte 2 232 ; CHECK: .byte 8 233 ; CHECK: .short 7 234 ; CHECK: .long 16 235 236 ; No Padding or LiveOuts 237 ; CHECK: .short 0 238 ; CHECK: .short 0 239 ; CHECK: .align 8 240 241 ; Records for the test_id function: 242 ; No large constants 243 244 ; The Statepoint ID: 245 ; CHECK: .quad 237 246 247 ; Instruction Offset 248 ; CHECK: .long .Ltmp5-test_id 249 250 ; Reserved: 251 ; CHECK: .short 0 252 253 ; NumLocations: 254 ; CHECK: .short 3 255 256 ; StkMapRecord[0]: 257 ; SmallConstant(0): 258 ; CHECK: .byte 4 259 ; CHECK: .byte 8 260 ; CHECK: .short 0 261 ; CHECK: .long 0 262 263 ; StkMapRecord[1]: 264 ; SmallConstant(0): 265 ; CHECK: .byte 4 266 ; CHECK: .byte 8 267 ; CHECK: .short 0 268 ; CHECK: .long 0 269 270 ; StkMapRecord[2]: 271 ; SmallConstant(0): 272 ; CHECK: .byte 4 273 ; CHECK: .byte 8 274 ; CHECK: .short 0 275 ; CHECK: .long 0 276 277 ; No padding or LiveOuts 278 ; CHECK: .short 0 279 ; CHECK: .short 0 280 ; CHECK: .align 8 281 282