1; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 2; 3; Note: Print verbose stackmaps using -debug-only=stackmaps. 4 5; CHECK: .section .llvm_stackmaps 6; CHECK-NEXT: __LLVM_StackMaps: 7; Header 8; CHECK-NEXT: .byte 3 9; CHECK-NEXT: .byte 0 10; CHECK-NEXT: .short 0 11; Num Functions 12; CHECK-NEXT: .long 15 13; Num LargeConstants 14; CHECK-NEXT: .long 3 15; Num Callsites 16; CHECK-NEXT: .long 19 17 18; Functions and stack size 19; CHECK-NEXT: .quad constantargs 20; CHECK-NEXT: .quad 160 21; CHECK-NEXT: .quad 1 22; CHECK-NEXT: .quad osrinline 23; CHECK-NEXT: .quad 160 24; CHECK-NEXT: .quad 1 25; CHECK-NEXT: .quad osrcold 26; CHECK-NEXT: .quad 160 27; CHECK-NEXT: .quad 1 28; CHECK-NEXT: .quad propertyRead 29; CHECK-NEXT: .quad 160 30; CHECK-NEXT: .quad 1 31; CHECK-NEXT: .quad propertyWrite 32; CHECK-NEXT: .quad 160 33; CHECK-NEXT: .quad 1 34; CHECK-NEXT: .quad jsVoidCall 35; CHECK-NEXT: .quad 160 36; CHECK-NEXT: .quad 1 37; CHECK-NEXT: .quad jsIntCall 38; CHECK-NEXT: .quad 160 39; CHECK-NEXT: .quad 1 40; CHECK-NEXT: .quad spilledValue 41; CHECK-NEXT: .quad 240 42; CHECK-NEXT: .quad 1 43; CHECK-NEXT: .quad spilledStackMapValue 44; CHECK-NEXT: .quad 200 45; CHECK-NEXT: .quad 1 46; CHECK-NEXT: .quad spillSubReg 47; CHECK-NEXT: .quad 168 48; CHECK-NEXT: .quad 1 49; CHECK-NEXT: .quad liveConstant 50; CHECK-NEXT: .quad 160 51; CHECK-NEXT: .quad 1 52; CHECK-NEXT: .quad directFrameIdx 53; CHECK-NEXT: .quad 200 54; CHECK-NEXT: .quad 2 55; CHECK-NEXT: .quad longid 56; CHECK-NEXT: .quad 160 57; CHECK-NEXT: .quad 4 58; CHECK-NEXT: .quad clobberScratch 59; CHECK-NEXT: .quad 168 60; CHECK-NEXT: .quad 1 61; CHECK-NEXT: .quad needsStackRealignment 62; CHECK-NEXT: .quad -1 63; CHECK-NEXT: .quad 1 64 65; Large Constants 66; CHECK-NEXT: .quad 2147483648 67; CHECK-NEXT: .quad 4294967295 68; CHECK-NEXT: .quad 4294967296 69 70; Callsites 71; Constant arguments 72; 73; CHECK-NEXT: .quad 1 74; CHECK-NEXT: .long .L{{.*}}-constantargs 75; CHECK-NEXT: .short 0 76; CHECK-NEXT: .short 12 77; SmallConstant 78; CHECK-NEXT: .byte 4 79; CHECK-NEXT: .byte 0 80; CHECK-NEXT: .short 8 81; CHECK-NEXT: .short 0 82; CHECK-NEXT: .short 0 83; CHECK-NEXT: .long -1 84; SmallConstant 85; CHECK-NEXT: .byte 4 86; CHECK-NEXT: .byte 0 87; CHECK-NEXT: .short 8 88; CHECK-NEXT: .short 0 89; CHECK-NEXT: .short 0 90; CHECK-NEXT: .long -1 91; SmallConstant 92; CHECK-NEXT: .byte 4 93; CHECK-NEXT: .byte 0 94; CHECK-NEXT: .short 8 95; CHECK-NEXT: .short 0 96; CHECK-NEXT: .short 0 97; CHECK-NEXT: .long 65536 98; SmallConstant 99; CHECK-NEXT: .byte 4 100; CHECK-NEXT: .byte 0 101; CHECK-NEXT: .short 8 102; CHECK-NEXT: .short 0 103; CHECK-NEXT: .short 0 104; CHECK-NEXT: .long 2000000000 105; SmallConstant 106; CHECK-NEXT: .byte 4 107; CHECK-NEXT: .byte 0 108; CHECK-NEXT: .short 8 109; CHECK-NEXT: .short 0 110; CHECK-NEXT: .short 0 111; CHECK-NEXT: .long 2147483647 112; SmallConstant 113; CHECK-NEXT: .byte 4 114; CHECK-NEXT: .byte 0 115; CHECK-NEXT: .short 8 116; CHECK-NEXT: .short 0 117; CHECK-NEXT: .short 0 118; CHECK-NEXT: .long -1 119; SmallConstant 120; CHECK-NEXT: .byte 4 121; CHECK-NEXT: .byte 0 122; CHECK-NEXT: .short 8 123; CHECK-NEXT: .short 0 124; CHECK-NEXT: .short 0 125; CHECK-NEXT: .long -1 126; SmallConstant 127; CHECK-NEXT: .byte 4 128; CHECK-NEXT: .byte 0 129; CHECK-NEXT: .short 8 130; CHECK-NEXT: .short 0 131; CHECK-NEXT: .short 0 132; CHECK-NEXT: .long 0 133; LargeConstant at index 0 134; CHECK-NEXT: .byte 5 135; CHECK-NEXT: .byte 0 136; CHECK-NEXT: .short 8 137; CHECK-NEXT: .short 0 138; CHECK-NEXT: .short 0 139; CHECK-NEXT: .long 0 140; LargeConstant at index 1 141; CHECK-NEXT: .byte 5 142; CHECK-NEXT: .byte 0 143; CHECK-NEXT: .short 8 144; CHECK-NEXT: .short 0 145; CHECK-NEXT: .short 0 146; CHECK-NEXT: .long 1 147; LargeConstant at index 2 148; CHECK-NEXT: .byte 5 149; CHECK-NEXT: .byte 0 150; CHECK-NEXT: .short 8 151; CHECK-NEXT: .short 0 152; CHECK-NEXT: .short 0 153; CHECK-NEXT: .long 2 154; SmallConstant 155; CHECK-NEXT: .byte 4 156; CHECK-NEXT: .byte 0 157; CHECK-NEXT: .short 8 158; CHECK-NEXT: .short 0 159; CHECK-NEXT: .short 0 160; CHECK-NEXT: .long -1 161 162define void @constantargs() { 163entry: 164 %0 = inttoptr i64 12345 to i8* 165 tail call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 1, i32 14, i8* %0, i32 0, i16 65535, i16 -1, i32 65536, i32 2000000000, i32 2147483647, i32 -1, i32 4294967295, i32 4294967296, i64 2147483648, i64 4294967295, i64 4294967296, i64 -1) 166 ret void 167} 168 169; Inline OSR Exit 170; 171; CHECK: .long .L{{.*}}-osrinline 172; CHECK-NEXT: .short 0 173; CHECK-NEXT: .short 2 174; CHECK-NEXT: .byte 1 175; CHECK-NEXT: .byte 0 176; CHECK-NEXT: .short 8 177; CHECK-NEXT: .short {{[0-9]+}} 178; CHECK-NEXT: .short 0 179; CHECK-NEXT: .long 0 180; CHECK-NEXT: .byte 1 181; CHECK-NEXT: .byte 0 182; CHECK-NEXT: .short 8 183; CHECK-NEXT: .short {{[0-9]+}} 184; CHECK-NEXT: .short 0 185; CHECK-NEXT: .long 0 186define void @osrinline(i64 %a, i64 %b) { 187entry: 188 ; Runtime void->void call. 189 call void inttoptr (i64 -559038737 to void ()*)() 190 ; Followed by inline OSR patchpoint with 12-byte shadow and 2 live vars. 191 call void (i64, i32, ...) @llvm.experimental.stackmap(i64 3, i32 12, i64 %a, i64 %b) 192 ret void 193} 194 195; Cold OSR Exit 196; 197; 2 live variables in register. 198; 199; CHECK: .long .L{{.*}}-osrcold 200; CHECK-NEXT: .short 0 201; CHECK-NEXT: .short 2 202; CHECK-NEXT: .byte 1 203; CHECK-NEXT: .byte 0 204; CHECK-NEXT: .short 8 205; CHECK-NEXT: .short {{[0-9]+}} 206; CHECK-NEXT: .short 0 207; CHECK-NEXT: .long 0 208; CHECK-NEXT: .byte 1 209; CHECK-NEXT: .byte 0 210; CHECK-NEXT: .short 8 211; CHECK-NEXT: .short {{[0-9]+}} 212; CHECK-NEXT: .short 0 213; CHECK-NEXT: .long 0 214define void @osrcold(i64 %a, i64 %b) { 215entry: 216 %test = icmp slt i64 %a, %b 217 br i1 %test, label %ret, label %cold 218cold: 219 ; OSR patchpoint with 12-byte nop-slide and 2 live vars. 220 %thunk = inttoptr i64 -559038737 to i8* 221 call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 4, i32 14, i8* %thunk, i32 0, i64 %a, i64 %b) 222 unreachable 223ret: 224 ret void 225} 226 227; Property Read 228; CHECK: .long .L{{.*}}-propertyRead 229; CHECK-NEXT: .short 0 230; CHECK-NEXT: .short 2 231; CHECK-NEXT: .byte 1 232; CHECK-NEXT: .byte 0 233; CHECK-NEXT: .short 8 234; CHECK-NEXT: .short {{[0-9]+}} 235; CHECK-NEXT: .short 0 236; CHECK-NEXT: .long 0 237; CHECK-NEXT: .byte 1 238; CHECK-NEXT: .byte 0 239; CHECK-NEXT: .short 8 240; CHECK-NEXT: .short {{[0-9]+}} 241; CHECK-NEXT: .short 0 242; CHECK-NEXT: .long 0 243define i64 @propertyRead(i64* %obj) { 244entry: 245 %resolveRead = inttoptr i64 -559038737 to i8* 246 %result = call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 5, i32 14, i8* %resolveRead, i32 1, i64* %obj) 247 %add = add i64 %result, 3 248 ret i64 %add 249} 250 251; Property Write 252; CHECK: .long .L{{.*}}-propertyWrite 253; CHECK-NEXT: .short 0 254; CHECK-NEXT: .short 2 255; CHECK-NEXT: .byte 1 256; CHECK-NEXT: .byte 0 257; CHECK-NEXT: .short 8 258; CHECK-NEXT: .short {{[0-9]+}} 259; CHECK-NEXT: .short 0 260; CHECK-NEXT: .long 0 261; CHECK-NEXT: .byte 1 262; CHECK-NEXT: .byte 0 263; CHECK-NEXT: .short 8 264; CHECK-NEXT: .short {{[0-9]+}} 265; CHECK-NEXT: .short 0 266; CHECK-NEXT: .long 0 267define void @propertyWrite(i64 %dummy1, i64* %obj, i64 %dummy2, i64 %a) { 268entry: 269 %resolveWrite = inttoptr i64 -559038737 to i8* 270 call anyregcc void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 6, i32 14, i8* %resolveWrite, i32 2, i64* %obj, i64 %a) 271 ret void 272} 273 274; Void JS Call 275; 276; 2 live variables in registers. 277; 278; CHECK: .long .L{{.*}}-jsVoidCall 279; CHECK-NEXT: .short 0 280; CHECK-NEXT: .short 2 281; CHECK-NEXT: .byte 1 282; CHECK-NEXT: .byte 0 283; CHECK-NEXT: .short 8 284; CHECK-NEXT: .short {{[0-9]+}} 285; CHECK-NEXT: .short 0 286; CHECK-NEXT: .long 0 287; CHECK-NEXT: .byte 1 288; CHECK-NEXT: .byte 0 289; CHECK-NEXT: .short 8 290; CHECK-NEXT: .short {{[0-9]+}} 291; CHECK-NEXT: .short 0 292; CHECK-NEXT: .long 0 293define void @jsVoidCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) { 294entry: 295 %resolveCall = inttoptr i64 -559038737 to i8* 296 call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 7, i32 14, i8* %resolveCall, i32 2, i64* %obj, i64 %arg, i64 %l1, i64 %l2) 297 ret void 298} 299 300; i64 JS Call 301; 302; 2 live variables in registers. 303; 304; CHECK: .long .L{{.*}}-jsIntCall 305; CHECK-NEXT: .short 0 306; CHECK-NEXT: .short 2 307; CHECK-NEXT: .byte 1 308; CHECK-NEXT: .byte 0 309; CHECK-NEXT: .short 8 310; CHECK-NEXT: .short {{[0-9]+}} 311; CHECK-NEXT: .short 0 312; CHECK-NEXT: .long 0 313; CHECK-NEXT: .byte 1 314; CHECK-NEXT: .byte 0 315; CHECK-NEXT: .short 8 316; CHECK-NEXT: .short {{[0-9]+}} 317; CHECK-NEXT: .short 0 318; CHECK-NEXT: .long 0 319define i64 @jsIntCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) { 320entry: 321 %resolveCall = inttoptr i64 -559038737 to i8* 322 %result = call i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 8, i32 14, i8* %resolveCall, i32 2, i64* %obj, i64 %arg, i64 %l1, i64 %l2) 323 %add = add i64 %result, 3 324 ret i64 %add 325} 326 327; Spilled stack map values. 328; 329; Verify 17 stack map entries. 330; 331; CHECK: .long .L{{.*}}-spilledValue 332; CHECK-NEXT: .short 0 333; CHECK-NEXT: .short 17 334; 335; Check that at least one is a spilled entry from the parameter area. 336; Location: Indirect r15 + XX 337; CHECK: .byte 3 338; CHECK-NEXT: .byte 0 339; CHECK-NEXT: .short 8 340; CHECK-NEXT: .short 15 341; CHECK-NEXT: .short 0 342; CHECK-NEXT: .long 343define void @spilledValue(i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16) { 344entry: 345 call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 11, i32 14, i8* null, i32 5, i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16) 346 ret void 347} 348 349; Spilled stack map values. 350; 351; Verify 17 stack map entries. 352; 353; CHECK: .long .L{{.*}}-spilledStackMapValue 354; CHECK-NEXT: .short 0 355; CHECK-NEXT: .short 17 356; 357; Check that at least one is a spilled entry from the parameter area. 358; Location: Indirect r15 + XX 359; CHECK: .byte 3 360; CHECK-NEXT: .byte 0 361; CHECK-NEXT: .short 8 362; CHECK-NEXT: .short 15 363; CHECK-NEXT: .short 0 364; CHECK-NEXT: .long 365define void @spilledStackMapValue(i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16) { 366entry: 367 call void (i64, i32, ...) @llvm.experimental.stackmap(i64 12, i32 16, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16) 368 ret void 369} 370 371; Spill a subregister stackmap operand. 372; 373; CHECK: .long .L{{.*}}-spillSubReg 374; CHECK-NEXT: .short 0 375; 4 locations 376; CHECK-NEXT: .short 1 377; 378; Check that the subregister operand is a 4-byte spill. 379; Location: Indirect, 4-byte, %r15 + 164 380; CHECK: .byte 3 381; CHECK-NEXT: .byte 0 382; CHECK-NEXT: .short 4 383; CHECK-NEXT: .short 15 384; CHECK-NEXT: .short 0 385; CHECK-NEXT: .long 164 386define void @spillSubReg(i64 %arg) #0 { 387bb: 388 br i1 undef, label %bb1, label %bb2 389 390bb1: 391 unreachable 392 393bb2: 394 %tmp = load i64, i64* inttoptr (i64 140685446136880 to i64*) 395 br i1 undef, label %bb16, label %bb17 396 397bb16: 398 unreachable 399 400bb17: 401 %tmp32 = trunc i64 %tmp to i32 402 br i1 undef, label %bb60, label %bb61 403 404bb60: 405 tail call void asm sideeffect "nopr %r0", "~{r0},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14}"() nounwind 406 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 13, i32 6, i32 %tmp32) 407 unreachable 408 409bb61: 410 unreachable 411} 412 413; Map a constant value. 414; 415; CHECK: .long .L{{.*}}-liveConstant 416; CHECK-NEXT: .short 0 417; 1 location 418; CHECK-NEXT: .short 1 419; Loc 0: SmallConstant 420; CHECK-NEXT: .byte 4 421; CHECK-NEXT: .byte 0 422; CHECK-NEXT: .short 8 423; CHECK-NEXT: .short 0 424; CHECK-NEXT: .short 0 425; CHECK-NEXT: .long 33 426 427define void @liveConstant() { 428 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 15, i32 6, i32 33) 429 ret void 430} 431 432; Directly map an alloca's address. 433; 434; Callsite 16 435; CHECK: .long .L{{.*}}-directFrameIdx 436; CHECK-NEXT: .short 0 437; 1 location 438; CHECK-NEXT: .short 1 439; Loc 0: Direct %r15 + ofs 440; CHECK-NEXT: .byte 2 441; CHECK-NEXT: .byte 0 442; CHECK-NEXT: .short 8 443; CHECK-NEXT: .short 15 444; CHECK-NEXT: .short 0 445; CHECK-NEXT: .long 446 447; Callsite 17 448; CHECK: .long .L{{.*}}-directFrameIdx 449; CHECK-NEXT: .short 0 450; 2 locations 451; CHECK-NEXT: .short 2 452; Loc 0: Direct %r15 + ofs 453; CHECK-NEXT: .byte 2 454; CHECK-NEXT: .byte 0 455; CHECK-NEXT: .short 8 456; CHECK-NEXT: .short 15 457; CHECK-NEXT: .short 0 458; CHECK-NEXT: .long 459; Loc 1: Direct %r15 + ofs 460; CHECK-NEXT: .byte 2 461; CHECK-NEXT: .byte 0 462; CHECK-NEXT: .short 8 463; CHECK-NEXT: .short 15 464; CHECK-NEXT: .short 0 465; CHECK-NEXT: .long 466define void @directFrameIdx() { 467entry: 468 %metadata1 = alloca i64, i32 3, align 8 469 store i64 11, i64* %metadata1 470 store i64 12, i64* %metadata1 471 store i64 13, i64* %metadata1 472 call void (i64, i32, ...) @llvm.experimental.stackmap(i64 16, i32 0, i64* %metadata1) 473 %metadata2 = alloca i8, i32 4, align 8 474 %metadata3 = alloca i16, i32 4, align 8 475 call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 17, i32 6, i8* null, i32 0, i8* %metadata2, i16* %metadata3) 476 ret void 477} 478 479; Test a 64-bit ID. 480; 481; CHECK: .quad 4294967295 482; CHECK: .long .L{{.*}}-longid 483; CHECK: .quad 4294967296 484; CHECK: .long .L{{.*}}-longid 485; CHECK: .quad 9223372036854775807 486; CHECK: .long .L{{.*}}-longid 487; CHECK: .quad -1 488; CHECK: .long .L{{.*}}-longid 489define void @longid() { 490entry: 491 tail call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 4294967295, i32 0, i8* null, i32 0) 492 tail call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 4294967296, i32 0, i8* null, i32 0) 493 tail call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 9223372036854775807, i32 0, i8* null, i32 0) 494 tail call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 -1, i32 0, i8* null, i32 0) 495 ret void 496} 497 498; Map a value when %r0 and %r1 are the only free registers. 499; The scratch registers should not be used for a live stackmap value. 500; 501; CHECK: .long .L{{.*}}-clobberScratch 502; CHECK-NEXT: .short 0 503; 1 location 504; CHECK-NEXT: .short 1 505; Loc 0: Indirect %r15 + offset 506; CHECK-NEXT: .byte 3 507; CHECK-NEXT: .byte 0 508; CHECK-NEXT: .short 4 509; CHECK-NEXT: .short 15 510; CHECK-NEXT: .short 0 511; CHECK-NEXT: .long 164 512define void @clobberScratch(i32 %a) { 513 tail call void asm sideeffect "nopr %r0", "~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14}"() nounwind 514 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 16, i32 8, i32 %a) 515 ret void 516} 517 518; A stack frame which needs to be realigned at runtime (to meet alignment 519; criteria for values on the stack) does not have a fixed frame size. 520; CHECK: .long .L{{.*}}-needsStackRealignment 521; CHECK-NEXT: .short 0 522; 0 locations 523; CHECK-NEXT: .short 0 524define void @needsStackRealignment() { 525 %val = alloca i64, i32 3, align 128 526 tail call void (...) @escape_values(i64* %val) 527; Note: Adding any non-constant to the stackmap would fail because we 528; expected to be able to address off the frame pointer. In a realigned 529; frame, we must use the stack pointer instead. This is a separate bug. 530 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 0, i32 0) 531 ret void 532} 533declare void @escape_values(...) 534 535declare void @llvm.experimental.stackmap(i64, i32, ...) 536declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...) 537declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...) 538