1; RUN: llc < %s -mtriple="x86_64-pc-linux-gnu" | FileCheck %s 2; RUN: llc < %s -mtriple="x86_64-pc-win64-coff" | 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 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. 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 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 66define i1 @test_id() gc "statepoint-example" { 67; CHECK-LABEL: test_id 68entry: 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 75declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...) 76declare i1 @llvm.experimental.gc.result.i1(i32) 77declare 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