Home | History | Annotate | Download | only in X86
      1 ; RUN: llc < %s -stack-symbol-ordering=0 -mtriple="x86_64-pc-linux-gnu" | FileCheck %s
      2 ; RUN: llc < %s -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 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 ; CHECK-NEXT:   .quad test_id
     98 ; CHECK-NEXT:   .quad 8
     99 
    100 ;
    101 ; test
    102 ;
    103 
    104 ; Statepoint ID
    105 ; CHECK-NEXT: .quad	0
    106 
    107 ; Callsites
    108 ; Constant arguments
    109 ; CHECK-NEXT: .long	.Ltmp1-test
    110 ; CHECK: .short	0
    111 ; CHECK: .short	11
    112 ; SmallConstant (0)
    113 ; CHECK: .byte	4
    114 ; CHECK: .byte	8
    115 ; CHECK: .short	0
    116 ; CHECK: .long	0
    117 ; SmallConstant (0)
    118 ; CHECK: .byte	4
    119 ; CHECK: .byte	8
    120 ; CHECK: .short	0
    121 ; CHECK: .long	0
    122 ; SmallConstant (2)
    123 ; CHECK: .byte	4
    124 ; CHECK: .byte	8
    125 ; CHECK: .short	0
    126 ; CHECK: .long	2
    127 ; Indirect Spill Slot [RSP+0]
    128 ; CHECK: .byte	3
    129 ; CHECK: .byte	8
    130 ; CHECK: .short	7
    131 ; CHECK: .long	16
    132 ; SmallConstant  (0)
    133 ; CHECK: .byte	4
    134 ; CHECK: .byte	8
    135 ; CHECK: .short	0
    136 ; CHECK: .long	0
    137 ; SmallConstant  (0)
    138 ; CHECK: .byte	4
    139 ; CHECK: .byte	8
    140 ; CHECK: .short	0
    141 ; CHECK: .long	0
    142 ; SmallConstant  (0)
    143 ; CHECK: .byte	4
    144 ; CHECK: .byte	8
    145 ; CHECK: .short	0
    146 ; CHECK: .long	0
    147 ; Indirect Spill Slot [RSP+16]
    148 ; CHECK: .byte	3
    149 ; CHECK: .byte	8
    150 ; CHECK: .short	7
    151 ; CHECK: .long	16
    152 ; Indirect Spill Slot [RSP+8]
    153 ; CHECK: .byte	3
    154 ; CHECK: .byte	8
    155 ; CHECK: .short	7
    156 ; CHECK: .long	8
    157 ; Indirect Spill Slot [RSP+16]
    158 ; CHECK: .byte	3
    159 ; CHECK: .byte	8
    160 ; CHECK: .short	7
    161 ; CHECK: .long	16
    162 ; Indirect Spill Slot [RSP+16]
    163 ; CHECK: .byte	3
    164 ; CHECK: .byte	8
    165 ; CHECK: .short	7
    166 ; CHECK: .long	16
    167 
    168 ; No Padding or LiveOuts
    169 ; CHECK: .short	0
    170 ; CHECK: .short	0
    171 ; CHECK: .p2align	3
    172 
    173 ;
    174 ; test_derived_arg
    175 
    176 ; Statepoint ID
    177 ; CHECK-NEXT: .quad	0
    178 
    179 ; Callsites
    180 ; Constant arguments
    181 ; CHECK-NEXT: .long	.Ltmp3-test_derived_arg
    182 ; CHECK: .short	0
    183 ; CHECK: .short	11
    184 ; SmallConstant (0)
    185 ; CHECK: .byte	4
    186 ; CHECK: .byte	8
    187 ; CHECK: .short	0
    188 ; CHECK: .long	0
    189 ; SmallConstant (2)
    190 ; CHECK: .byte	4
    191 ; CHECK: .byte	8
    192 ; CHECK: .short	0
    193 ; CHECK: .long	2
    194 ; Indirect Spill Slot [RSP+0]
    195 ; CHECK: .byte	3
    196 ; CHECK: .byte	8
    197 ; CHECK: .short	7
    198 ; CHECK: .long	16
    199 ; SmallConstant  (0)
    200 ; CHECK: .byte	4
    201 ; CHECK: .byte	8
    202 ; CHECK: .short	0
    203 ; CHECK: .long	0
    204 ; SmallConstant  (0)
    205 ; CHECK: .byte	4
    206 ; CHECK: .byte	8
    207 ; CHECK: .short	0
    208 ; CHECK: .long	0
    209 ; SmallConstant  (0)
    210 ; CHECK: .byte	4
    211 ; CHECK: .byte	8
    212 ; CHECK: .short	0
    213 ; CHECK: .long	0
    214 ; Indirect Spill Slot [RSP+16]
    215 ; CHECK: .byte	3
    216 ; CHECK: .byte	8
    217 ; CHECK: .short	7
    218 ; CHECK: .long	16
    219 ; Indirect Spill Slot [RSP+8]
    220 ; CHECK: .byte	3
    221 ; CHECK: .byte	8
    222 ; CHECK: .short	7
    223 ; CHECK: .long	8
    224 ; Indirect Spill Slot [RSP+16]
    225 ; CHECK: .byte	3
    226 ; CHECK: .byte	8
    227 ; CHECK: .short	7
    228 ; CHECK: .long	16
    229 ; Indirect Spill Slot [RSP+16]
    230 ; CHECK: .byte	3
    231 ; CHECK: .byte	8
    232 ; CHECK: .short	7
    233 ; CHECK: .long	16
    234 
    235 ; No Padding or LiveOuts
    236 ; CHECK: .short	0
    237 ; CHECK: .short	0
    238 ; CHECK: .p2align	3
    239 
    240 ; Records for the test_id function:
    241 
    242 ; The Statepoint ID:
    243 ; CHECK-NEXT: .quad	237
    244 
    245 ; Instruction Offset
    246 ; CHECK-NEXT: .long	.Ltmp5-test_id
    247 
    248 ; Reserved:
    249 ; CHECK: .short	0
    250 
    251 ; NumLocations:
    252 ; CHECK: .short	3
    253 
    254 ; StkMapRecord[0]:
    255 ; SmallConstant(0):
    256 ; CHECK: .byte	4
    257 ; CHECK: .byte	8
    258 ; CHECK: .short	0
    259 ; CHECK: .long	0
    260 
    261 ; StkMapRecord[1]:
    262 ; SmallConstant(0):
    263 ; CHECK: .byte	4
    264 ; CHECK: .byte	8
    265 ; CHECK: .short	0
    266 ; CHECK: .long	0
    267 
    268 ; StkMapRecord[2]:
    269 ; SmallConstant(0):
    270 ; CHECK: .byte	4
    271 ; CHECK: .byte	8
    272 ; CHECK: .short	0
    273 ; CHECK: .long	0
    274 
    275 ; No padding or LiveOuts
    276 ; CHECK: .short	0
    277 ; CHECK: .short	0
    278 ; CHECK: .p2align	3
    279 
    280