1; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7 | FileCheck %s 2; 3; Note: Print verbose stackmaps using -debug-only=stackmaps. 4 5; CHECK-LABEL: .section __LLVM_STACKMAPS,__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 17 13; Num LargeConstants 14; CHECK-NEXT: .long 4 15; Num Callsites 16; CHECK-NEXT: .long 21 17 18; Functions and stack size 19; CHECK-NEXT: .quad _constantargs 20; CHECK-NEXT: .quad 8 21; CHECK-NEXT: .quad 1 22; CHECK-NEXT: .quad _osrinline 23; CHECK-NEXT: .quad 24 24; CHECK-NEXT: .quad 1 25; CHECK-NEXT: .quad _osrcold 26; CHECK-NEXT: .quad 8 27; CHECK-NEXT: .quad 1 28; CHECK-NEXT: .quad _propertyRead 29; CHECK-NEXT: .quad 8 30; CHECK-NEXT: .quad 1 31; CHECK-NEXT: .quad _propertyWrite 32; CHECK-NEXT: .quad 8 33; CHECK-NEXT: .quad 1 34; CHECK-NEXT: .quad _jsVoidCall 35; CHECK-NEXT: .quad 8 36; CHECK-NEXT: .quad 1 37; CHECK-NEXT: .quad _jsIntCall 38; CHECK-NEXT: .quad 8 39; CHECK-NEXT: .quad 1 40; CHECK-NEXT: .quad _spilledValue 41; CHECK-NEXT: .quad 8 42; CHECK-NEXT: .quad 1 43; CHECK-NEXT: .quad _spilledStackMapValue 44; CHECK-NEXT: .quad 8 45; CHECK-NEXT: .quad 1 46; CHECK-NEXT: .quad _spillSubReg 47; CHECK-NEXT: .quad 56 48; CHECK-NEXT: .quad 1 49; CHECK-NEXT: .quad _subRegOffset 50; CHECK-NEXT: .quad 56 51; CHECK-NEXT: .quad 1 52; CHECK-NEXT: .quad _liveConstant 53; CHECK-NEXT: .quad 8 54; CHECK-NEXT: .quad 1 55; CHECK-NEXT: .quad _directFrameIdx 56; CHECK-NEXT: .quad 56 57; CHECK-NEXT: .quad 2 58; CHECK-NEXT: .quad _longid 59; CHECK-NEXT: .quad 8 60; CHECK-NEXT: .quad 4 61; CHECK-NEXT: .quad _clobberScratch 62; CHECK-NEXT: .quad 56 63; CHECK-NEXT: .quad 1 64; CHECK-NEXT: .quad _needsStackRealignment 65; CHECK-NEXT: .quad -1 66; CHECK-NEXT: .quad 1 67; CHECK-NEXT: .quad _floats 68; CHECK-NEXT: .quad 24 69; CHECK-NEXT: .quad 1 70 71; Large Constants 72; CHECK-NEXT: .quad 2147483648 73; CHECK-NEXT: .quad 4294967295 74; CHECK-NEXT: .quad 4294967296 75; CHECK-NEXT: .quad 4294967297 76 77; Callsites 78; Constant arguments 79; 80; CHECK-NEXT: .quad 1 81; CHECK-NEXT: .long L{{.*}}-_constantargs 82; CHECK-NEXT: .short 0 83; CHECK-NEXT: .short 14 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 -1 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 65536 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 2000000000 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 2147483647 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 -1 133; SmallConstant 134; CHECK-NEXT: .byte 4 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 0 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 0 147; LargeConstant at index 1 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 1 154; LargeConstant at index 2 155; CHECK-NEXT: .byte 5 156; CHECK-NEXT: .byte 0 157; CHECK-NEXT: .short 8 158; CHECK-NEXT: .short 0 159; CHECK-NEXT: .short 0 160; CHECK-NEXT: .long 2 161; SmallConstant 162; CHECK-NEXT: .byte 4 163; CHECK-NEXT: .byte 0 164; CHECK-NEXT: .short 8 165; CHECK-NEXT: .short 0 166; CHECK-NEXT: .short 0 167; CHECK-NEXT: .long -1 168; SmallConstant 169; CHECK-NEXT: .byte 4 170; CHECK-NEXT: .byte 0 171; CHECK-NEXT: .short 8 172; CHECK-NEXT: .short 0 173; CHECK-NEXT: .short 0 174; CHECK-NEXT: .long 66 175; LargeConstant at index 3 176; CHECK-NEXT: .byte 5 177; CHECK-NEXT: .byte 0 178; CHECK-NEXT: .short 8 179; CHECK-NEXT: .short 0 180; CHECK-NEXT: .short 0 181; CHECK-NEXT: .long 3 182 183define void @constantargs() { 184entry: 185 %0 = inttoptr i64 12345 to ptr 186 tail call void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 1, i32 15, ptr %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, i128 66, i128 4294967297) 187 ret void 188} 189 190; Inline OSR Exit 191; 192; CHECK-LABEL: .long L{{.*}}-_osrinline 193; CHECK-NEXT: .short 0 194; CHECK-NEXT: .short 2 195; CHECK-NEXT: .byte 1 196; CHECK-NEXT: .byte 0 197; CHECK-NEXT: .short 8 198; CHECK-NEXT: .short {{[0-9]+}} 199; CHECK-NEXT: .short 0 200; CHECK-NEXT: .long 0 201; CHECK-NEXT: .byte 1 202; CHECK-NEXT: .byte 0 203; CHECK-NEXT: .short 8 204; CHECK-NEXT: .short {{[0-9]+}} 205; CHECK-NEXT: .short 0 206; CHECK-NEXT: .long 0 207define void @osrinline(i64 %a, i64 %b) { 208entry: 209 ; Runtime void->void call. 210 call void inttoptr (i64 -559038737 to ptr)() 211 ; Followed by inline OSR patchpoint with 12-byte shadow and 2 live vars. 212 call void (i64, i32, ...) @llvm.experimental.stackmap(i64 3, i32 12, i64 %a, i64 %b) 213 ret void 214} 215 216; Cold OSR Exit 217; 218; 2 live variables in register. 219; 220; CHECK-LABEL: .long L{{.*}}-_osrcold 221; CHECK-NEXT: .short 0 222; CHECK-NEXT: .short 2 223; CHECK-NEXT: .byte 1 224; CHECK-NEXT: .byte 0 225; CHECK-NEXT: .short 8 226; CHECK-NEXT: .short {{[0-9]+}} 227; CHECK-NEXT: .short 0 228; CHECK-NEXT: .long 0 229; CHECK-NEXT: .byte 1 230; CHECK-NEXT: .byte 0 231; CHECK-NEXT: .short 8 232; CHECK-NEXT: .short {{[0-9]+}} 233; CHECK-NEXT: .short 0 234; CHECK-NEXT: .long 0 235define void @osrcold(i64 %a, i64 %b) { 236entry: 237 %test = icmp slt i64 %a, %b 238 br i1 %test, label %ret, label %cold 239cold: 240 ; OSR patchpoint with 12-byte nop-slide and 2 live vars. 241 %thunk = inttoptr i64 -559038737 to ptr 242 call void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 4, i32 15, ptr %thunk, i32 0, i64 %a, i64 %b) 243 unreachable 244ret: 245 ret void 246} 247 248; Property Read 249; CHECK-LABEL: .long L{{.*}}-_propertyRead 250; CHECK-NEXT: .short 0 251; CHECK-NEXT: .short 2 252; CHECK-NEXT: .byte 1 253; CHECK-NEXT: .byte 0 254; CHECK-NEXT: .short 8 255; CHECK-NEXT: .short {{[0-9]+}} 256; CHECK-NEXT: .short 0 257; CHECK-NEXT: .long 0 258; CHECK-NEXT: .byte 1 259; CHECK-NEXT: .byte 0 260; CHECK-NEXT: .short 8 261; CHECK-NEXT: .short {{[0-9]+}} 262; CHECK-NEXT: .short 0 263; CHECK-NEXT: .long 0 264define i64 @propertyRead(ptr %obj) { 265entry: 266 %resolveRead = inttoptr i64 -559038737 to ptr 267 %result = call anyregcc i64 (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.i64(i64 5, i32 15, ptr %resolveRead, i32 1, ptr %obj) 268 %add = add i64 %result, 3 269 ret i64 %add 270} 271 272; Property Write 273; CHECK-LABEL: .long L{{.*}}-_propertyWrite 274; CHECK-NEXT: .short 0 275; CHECK-NEXT: .short 2 276; CHECK-NEXT: .byte 1 277; CHECK-NEXT: .byte 0 278; CHECK-NEXT: .short 8 279; CHECK-NEXT: .short {{[0-9]+}} 280; CHECK-NEXT: .short 0 281; CHECK-NEXT: .long 0 282; CHECK-NEXT: .byte 1 283; CHECK-NEXT: .byte 0 284; CHECK-NEXT: .short 8 285; CHECK-NEXT: .short {{[0-9]+}} 286; CHECK-NEXT: .short 0 287; CHECK-NEXT: .long 0 288define void @propertyWrite(i64 %dummy1, ptr %obj, i64 %dummy2, i64 %a) { 289entry: 290 %resolveWrite = inttoptr i64 -559038737 to ptr 291 call anyregcc void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 6, i32 15, ptr %resolveWrite, i32 2, ptr %obj, i64 %a) 292 ret void 293} 294 295; Void JS Call 296; 297; 2 live variables in registers. 298; 299; CHECK-LABEL: .long L{{.*}}-_jsVoidCall 300; CHECK-NEXT: .short 0 301; CHECK-NEXT: .short 2 302; CHECK-NEXT: .byte 1 303; CHECK-NEXT: .byte 0 304; CHECK-NEXT: .short 8 305; CHECK-NEXT: .short {{[0-9]+}} 306; CHECK-NEXT: .short 0 307; CHECK-NEXT: .long 0 308; CHECK-NEXT: .byte 1 309; CHECK-NEXT: .byte 0 310; CHECK-NEXT: .short 8 311; CHECK-NEXT: .short {{[0-9]+}} 312; CHECK-NEXT: .short 0 313; CHECK-NEXT: .long 0 314define void @jsVoidCall(i64 %dummy1, ptr %obj, i64 %arg, i64 %l1, i64 %l2) { 315entry: 316 %resolveCall = inttoptr i64 -559038737 to ptr 317 call void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 7, i32 15, ptr %resolveCall, i32 2, ptr %obj, i64 %arg, i64 %l1, i64 %l2) 318 ret void 319} 320 321; i64 JS Call 322; 323; 2 live variables in registers. 324; 325; CHECK-LABEL: .long L{{.*}}-_jsIntCall 326; CHECK-NEXT: .short 0 327; CHECK-NEXT: .short 2 328; CHECK-NEXT: .byte 1 329; CHECK-NEXT: .byte 0 330; CHECK-NEXT: .short 8 331; CHECK-NEXT: .short {{[0-9]+}} 332; CHECK-NEXT: .short 0 333; CHECK-NEXT: .long 0 334; CHECK-NEXT: .byte 1 335; CHECK-NEXT: .byte 0 336; CHECK-NEXT: .short 8 337; CHECK-NEXT: .short {{[0-9]+}} 338; CHECK-NEXT: .short 0 339; CHECK-NEXT: .long 0 340define i64 @jsIntCall(i64 %dummy1, ptr %obj, i64 %arg, i64 %l1, i64 %l2) { 341entry: 342 %resolveCall = inttoptr i64 -559038737 to ptr 343 %result = call i64 (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.i64(i64 8, i32 15, ptr %resolveCall, i32 2, ptr %obj, i64 %arg, i64 %l1, i64 %l2) 344 %add = add i64 %result, 3 345 ret i64 %add 346} 347 348; Spilled stack map values. 349; 350; Verify 17 stack map entries. 351; 352; CHECK-LABEL: .long L{{.*}}-_spilledValue 353; CHECK-NEXT: .short 0 354; CHECK-NEXT: .short 17 355; 356; Check that at least one is a spilled entry from RBP. 357; Location: Indirect RBP + ... 358; CHECK: .byte 3 359; CHECK-NEXT: .byte 0 360; CHECK-NEXT: .short 8 361; CHECK-NEXT: .short 6 362; CHECK-NEXT: .short 0 363; CHECK-NEXT: .long 364define 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) { 365entry: 366 call void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 11, i32 15, ptr 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) 367 ret void 368} 369 370; Spilled stack map values. 371; 372; Verify 17 stack map entries. 373; 374; CHECK-LABEL: .long L{{.*}}-_spilledStackMapValue 375; CHECK-NEXT: .short 0 376; CHECK-NEXT: .short 17 377; 378; Check that at least one is a spilled entry from RBP. 379; Location: Indirect RBP + ... 380; CHECK: .byte 3 381; CHECK-NEXT: .byte 0 382; CHECK-NEXT: .short 8 383; CHECK-NEXT: .short 6 384; CHECK-NEXT: .short 0 385; CHECK-NEXT: .long 386define webkit_jscc 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) { 387entry: 388 call void (i64, i32, ...) @llvm.experimental.stackmap(i64 12, i32 15, 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) 389 ret void 390} 391 392; Spill a subregister stackmap operand. 393; 394; CHECK-LABEL: .long L{{.*}}-_spillSubReg 395; CHECK-NEXT: .short 0 396; 4 locations 397; CHECK-NEXT: .short 1 398; 399; Check that the subregister operand is a 4-byte spill. 400; Location: Indirect, 4-byte, RBP + ... 401; CHECK: .byte 3 402; CHECK-NEXT: .byte 0 403; CHECK-NEXT: .short 4 404; CHECK-NEXT: .short 6 405; CHECK-NEXT: .short 0 406; CHECK-NEXT: .long 407define void @spillSubReg(i64 %arg) #0 { 408bb: 409 br i1 undef, label %bb1, label %bb2 410 411bb1: 412 unreachable 413 414bb2: 415 %tmp = load i64, ptr inttoptr (i64 140685446136880 to ptr) 416 br i1 undef, label %bb16, label %bb17 417 418bb16: 419 unreachable 420 421bb17: 422 %tmp32 = trunc i64 %tmp to i32 423 br i1 undef, label %bb60, label %bb61 424 425bb60: 426 tail call void asm sideeffect "nop", "~{ax},~{bx},~{cx},~{dx},~{bp},~{si},~{di},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"() nounwind 427 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 13, i32 5, i32 %tmp32) 428 unreachable 429 430bb61: 431 unreachable 432} 433 434; Map a single byte subregister. There is no DWARF register number, so 435; we expect the register to be encoded with the proper size and spill offset. We don't know which 436; 437; CHECK-LABEL: .long L{{.*}}-_subRegOffset 438; CHECK-NEXT: .short 0 439; 2 locations 440; CHECK-NEXT: .short 2 441; 442; Check that the subregister operands are 1-byte spills. 443; Location 0: Register, 4-byte, AL 444; CHECK-NEXT: .byte 1 445; CHECK-NEXT: .byte 0 446; CHECK-NEXT: .short 1 447; CHECK-NEXT: .short 0 448; CHECK-NEXT: .short 0 449; CHECK-NEXT: .long 0 450; 451; Location 1: Register, 4-byte, BL 452; CHECK-NEXT: .byte 1 453; CHECK-NEXT: .byte 0 454; CHECK-NEXT: .short 1 455; CHECK-NEXT: .short 3 456; CHECK-NEXT: .short 0 457; CHECK-NEXT: .long 0 458define void @subRegOffset(i16 %arg) { 459 %v = mul i16 %arg, 5 460 %a0 = trunc i16 %v to i8 461 tail call void asm sideeffect "nop", "~{bx}"() nounwind 462 %arghi = lshr i16 %v, 8 463 %a1 = trunc i16 %arghi to i8 464 tail call void asm sideeffect "nop", "~{cx},~{dx},~{bp},~{si},~{di},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"() nounwind 465 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 14, i32 5, i8 %a0, i8 %a1) 466 ret void 467} 468 469; Map a constant value. 470; 471; CHECK-LABEL: .long L{{.*}}-_liveConstant 472; CHECK-NEXT: .short 0 473; 1 location 474; CHECK-NEXT: .short 1 475; Loc 0: SmallConstant 476; CHECK-NEXT: .byte 4 477; CHECK-NEXT: .byte 0 478; CHECK-NEXT: .short 8 479; CHECK-NEXT: .short 0 480; CHECK-NEXT: .short 0 481; CHECK-NEXT: .long 33 482 483define void @liveConstant() { 484 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 15, i32 5, i32 33) 485 ret void 486} 487 488; Directly map an alloca's address. 489; 490; Callsite 16 491; CHECK-LABEL: .long L{{.*}}-_directFrameIdx 492; CHECK-NEXT: .short 0 493; 1 location 494; CHECK-NEXT: .short 1 495; Loc 0: Direct RBP - ofs 496; CHECK-NEXT: .byte 2 497; CHECK-NEXT: .byte 0 498; CHECK-NEXT: .short 8 499; CHECK-NEXT: .short 6 500; CHECK-NEXT: .short 0 501; CHECK-NEXT: .long 502 503; Callsite 17 504; CHECK-LABEL: .long L{{.*}}-_directFrameIdx 505; CHECK-NEXT: .short 0 506; 2 locations 507; CHECK-NEXT: .short 2 508; Loc 0: Direct RBP - ofs 509; CHECK-NEXT: .byte 2 510; CHECK-NEXT: .byte 0 511; CHECK-NEXT: .short 8 512; CHECK-NEXT: .short 6 513; CHECK-NEXT: .short 0 514; CHECK-NEXT: .long 515; Loc 1: Direct RBP - ofs 516; CHECK-NEXT: .byte 2 517; CHECK-NEXT: .byte 0 518; CHECK-NEXT: .short 8 519; CHECK-NEXT: .short 6 520; CHECK-NEXT: .short 0 521; CHECK-NEXT: .long 522define void @directFrameIdx() { 523entry: 524 %metadata1 = alloca i64, i32 3, align 8 525 store i64 11, ptr %metadata1 526 store i64 12, ptr %metadata1 527 store i64 13, ptr %metadata1 528 call void (i64, i32, ...) @llvm.experimental.stackmap(i64 16, i32 0, ptr %metadata1) 529 %metadata2 = alloca i8, i32 4, align 8 530 %metadata3 = alloca i16, i32 4, align 8 531 call void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 17, i32 5, ptr null, i32 0, ptr %metadata2, ptr %metadata3) 532 ret void 533} 534 535; Test a 64-bit ID. 536; 537; CHECK: .quad 4294967295 538; CHECK-LABEL: .long L{{.*}}-_longid 539; CHECK: .quad 4294967296 540; CHECK-LABEL: .long L{{.*}}-_longid 541; CHECK: .quad 9223372036854775807 542; CHECK-LABEL: .long L{{.*}}-_longid 543; CHECK: .quad -1 544; CHECK-LABEL: .long L{{.*}}-_longid 545define void @longid() { 546entry: 547 tail call void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 4294967295, i32 0, ptr null, i32 0) 548 tail call void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 4294967296, i32 0, ptr null, i32 0) 549 tail call void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 9223372036854775807, i32 0, ptr null, i32 0) 550 tail call void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 -1, i32 0, ptr null, i32 0) 551 ret void 552} 553 554; Map a value when R11 is the only free register. 555; The scratch register should not be used for a live stackmap value. 556; 557; CHECK-LABEL: .long L{{.*}}-_clobberScratch 558; CHECK-NEXT: .short 0 559; 1 location 560; CHECK-NEXT: .short 1 561; Loc 0: Indirect fp - offset 562; CHECK-NEXT: .byte 3 563; CHECK-NEXT: .byte 0 564; CHECK-NEXT: .short 4 565; CHECK-NEXT: .short 6 566; CHECK-NEXT: .short 0 567; CHECK-NEXT: .long -{{[0-9]+}} 568define void @clobberScratch(i32 %a) { 569 tail call void asm sideeffect "nop", "~{ax},~{bx},~{cx},~{dx},~{bp},~{si},~{di},~{r8},~{r9},~{r10},~{r12},~{r13},~{r14},~{r15}"() nounwind 570 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 16, i32 8, i32 %a) 571 ret void 572} 573 574; A stack frame which needs to be realigned at runtime (to meet alignment 575; criteria for values on the stack) does not have a fixed frame size. 576; CHECK-LABEL: .long L{{.*}}-_needsStackRealignment 577; CHECK-NEXT: .short 0 578; 0 locations 579; CHECK-NEXT: .short 0 580define void @needsStackRealignment() { 581 %val = alloca i64, i32 3, align 128 582 tail call void (...) @escape_values(ptr %val) 583; Note: Adding any non-constant to the stackmap would fail because we 584; expected to be able to address off the frame pointer. In a realigned 585; frame, we must use the stack pointer instead. This is a separate bug. 586 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 0, i32 0) 587 ret void 588} 589declare void @escape_values(...) 590 591; CHECK-LABEL: .long L{{.*}}-_floats 592; CHECK-NEXT: .short 0 593; Num Locations 594; CHECK-NEXT: .short 6 595; Loc 0: constant float stored to FP register 596; CHECK-NEXT: .byte 1 597; CHECK-NEXT: .byte 0 598; CHECK-NEXT: .short 16 599; CHECK-NEXT: .short {{.*}} 600; CHECK-NEXT: .short 0 601; CHECK-NEXT: .long 0 602; Loc 0: constant double stored to FP register 603; CHECK-NEXT: .byte 1 604; CHECK-NEXT: .byte 0 605; CHECK-NEXT: .short 16 606; CHECK-NEXT: .short {{.*}} 607; CHECK-NEXT: .short 0 608; CHECK-NEXT: .long 0 609; Loc 1: float value in FP register 610; CHECK-NEXT: .byte 1 611; CHECK-NEXT: .byte 0 612; CHECK-NEXT: .short 16 613; CHECK-NEXT: .short {{.*}} 614; CHECK-NEXT: .short 0 615; CHECK-NEXT: .long 0 616; Loc 2: double value in FP register 617; CHECK-NEXT: .byte 1 618; CHECK-NEXT: .byte 0 619; CHECK-NEXT: .short 16 620; CHECK-NEXT: .short {{.*}} 621; CHECK-NEXT: .short 0 622; CHECK-NEXT: .long 0 623; Loc 3: float on stack 624; CHECK-NEXT: .byte 2 625; CHECK-NEXT: .byte 0 626; CHECK-NEXT: .short 8 627; CHECK-NEXT: .short {{.*}} 628; CHECK-NEXT: .short 0 629; CHECK-NEXT: .long -{{.*}} 630; Loc 4: double on stack 631; CHECK-NEXT: .byte 2 632; CHECK-NEXT: .byte 0 633; CHECK-NEXT: .short 8 634; CHECK-NEXT: .short {{.*}} 635; CHECK-NEXT: .short 0 636; CHECK-NEXT: .long -{{.*}} 637define void @floats(float %f, double %g) { 638 %ff = alloca float 639 %gg = alloca double 640 call void (i64, i32, ...) @llvm.experimental.stackmap(i64 888, i32 0, float 1.25, 641 double 1.5, float %f, double %g, ptr %ff, ptr %gg) 642 ret void 643} 644 645declare void @llvm.experimental.stackmap(i64, i32, ...) 646declare void @llvm.experimental.patchpoint.void(i64, i32, ptr, i32, ...) 647declare i64 @llvm.experimental.patchpoint.i64(i64, i32, ptr, i32, ...) 648