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 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 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