Home | History | Annotate | Download | only in X86
      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