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 8target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128" 9 10declare zeroext i1 @return_i1() 11 12define 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 24entry: 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. 40define 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 53entry: 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 66define i1 @test_id() gc "statepoint-example" { 67; CHECK-LABEL: test_id 68entry: 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 75declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...) 76declare i1 @llvm.experimental.gc.result.i1(token) 77declare 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