1; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7 -disable-fp-elim | 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; CHECK-NEXT: .long 0 8; Num Functions 9; CHECK-NEXT: .long 14 10; CHECK-NEXT: .long _constantargs 11; CHECK-NEXT: .long 8 12; CHECK-NEXT: .long _osrinline 13; CHECK-NEXT: .long 24 14; CHECK-NEXT: .long _osrcold 15; CHECK-NEXT: .long 8 16; CHECK-NEXT: .long _propertyRead 17; CHECK-NEXT: .long 8 18; CHECK-NEXT: .long _propertyWrite 19; CHECK-NEXT: .long 8 20; CHECK-NEXT: .long _jsVoidCall 21; CHECK-NEXT: .long 8 22; CHECK-NEXT: .long _jsIntCall 23; CHECK-NEXT: .long 8 24; CHECK-NEXT: .long _spilledValue 25; CHECK-NEXT: .long 56 26; CHECK-NEXT: .long _spilledStackMapValue 27; CHECK-NEXT: .long 56 28; CHECK-NEXT: .long _spillSubReg 29; CHECK-NEXT: .long 56 30; CHECK-NEXT: .long _subRegOffset 31; CHECK-NEXT: .long 56 32; CHECK-NEXT: .long _liveConstant 33; CHECK-NEXT: .long 8 34; CHECK-NEXT: .long _directFrameIdx 35; CHECK-NEXT: .long 56 36; CHECK-NEXT: .long _longid 37; CHECK-NEXT: .long 8 38; Num LargeConstants 39; CHECK-NEXT: .long 3 40; CHECK-NEXT: .quad 2147483648 41; CHECK-NEXT: .quad 4294967295 42; CHECK-NEXT: .quad 4294967296 43; Num Callsites 44; CHECK-NEXT: .long 18 45 46; Constant arguments 47; 48; CHECK-NEXT: .quad 1 49; CHECK-NEXT: .long L{{.*}}-_constantargs 50; CHECK-NEXT: .short 0 51; CHECK-NEXT: .short 12 52; SmallConstant 53; CHECK-NEXT: .byte 4 54; CHECK-NEXT: .byte 8 55; CHECK-NEXT: .short 0 56; CHECK-NEXT: .long -1 57; SmallConstant 58; CHECK-NEXT: .byte 4 59; CHECK-NEXT: .byte 8 60; CHECK-NEXT: .short 0 61; CHECK-NEXT: .long -1 62; SmallConstant 63; CHECK-NEXT: .byte 4 64; CHECK-NEXT: .byte 8 65; CHECK-NEXT: .short 0 66; CHECK-NEXT: .long 65536 67; SmallConstant 68; CHECK-NEXT: .byte 4 69; CHECK-NEXT: .byte 8 70; CHECK-NEXT: .short 0 71; CHECK-NEXT: .long 2000000000 72; SmallConstant 73; CHECK-NEXT: .byte 4 74; CHECK-NEXT: .byte 8 75; CHECK-NEXT: .short 0 76; CHECK-NEXT: .long 2147483647 77; SmallConstant 78; CHECK-NEXT: .byte 4 79; CHECK-NEXT: .byte 8 80; CHECK-NEXT: .short 0 81; CHECK-NEXT: .long -1 82; SmallConstant 83; CHECK-NEXT: .byte 4 84; CHECK-NEXT: .byte 8 85; CHECK-NEXT: .short 0 86; CHECK-NEXT: .long -1 87; SmallConstant 88; CHECK-NEXT: .byte 4 89; CHECK-NEXT: .byte 8 90; CHECK-NEXT: .short 0 91; CHECK-NEXT: .long 0 92; LargeConstant at index 0 93; CHECK-NEXT: .byte 5 94; CHECK-NEXT: .byte 8 95; CHECK-NEXT: .short 0 96; CHECK-NEXT: .long 0 97; LargeConstant at index 1 98; CHECK-NEXT: .byte 5 99; CHECK-NEXT: .byte 8 100; CHECK-NEXT: .short 0 101; CHECK-NEXT: .long 1 102; LargeConstant at index 2 103; CHECK-NEXT: .byte 5 104; CHECK-NEXT: .byte 8 105; CHECK-NEXT: .short 0 106; CHECK-NEXT: .long 2 107; SmallConstant 108; CHECK-NEXT: .byte 4 109; CHECK-NEXT: .byte 8 110; CHECK-NEXT: .short 0 111; CHECK-NEXT: .long -1 112 113define void @constantargs() { 114entry: 115 %0 = inttoptr i64 12345 to i8* 116 tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 1, i32 15, 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) 117 ret void 118} 119 120; Inline OSR Exit 121; 122; CHECK-LABEL: .long L{{.*}}-_osrinline 123; CHECK-NEXT: .short 0 124; CHECK-NEXT: .short 2 125; CHECK-NEXT: .byte 1 126; CHECK-NEXT: .byte 8 127; CHECK-NEXT: .short {{[0-9]+}} 128; CHECK-NEXT: .long 0 129; CHECK-NEXT: .byte 1 130; CHECK-NEXT: .byte 8 131; CHECK-NEXT: .short {{[0-9]+}} 132; CHECK-NEXT: .long 0 133define void @osrinline(i64 %a, i64 %b) { 134entry: 135 ; Runtime void->void call. 136 call void inttoptr (i64 -559038737 to void ()*)() 137 ; Followed by inline OSR patchpoint with 12-byte shadow and 2 live vars. 138 call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 3, i32 12, i64 %a, i64 %b) 139 ret void 140} 141 142; Cold OSR Exit 143; 144; 2 live variables in register. 145; 146; CHECK-LABEL: .long L{{.*}}-_osrcold 147; CHECK-NEXT: .short 0 148; CHECK-NEXT: .short 2 149; CHECK-NEXT: .byte 1 150; CHECK-NEXT: .byte 8 151; CHECK-NEXT: .short {{[0-9]+}} 152; CHECK-NEXT: .long 0 153; CHECK-NEXT: .byte 1 154; CHECK-NEXT: .byte 8 155; CHECK-NEXT: .short {{[0-9]+}} 156; CHECK-NEXT: .long 0 157define void @osrcold(i64 %a, i64 %b) { 158entry: 159 %test = icmp slt i64 %a, %b 160 br i1 %test, label %ret, label %cold 161cold: 162 ; OSR patchpoint with 12-byte nop-slide and 2 live vars. 163 %thunk = inttoptr i64 -559038737 to i8* 164 call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 4, i32 15, i8* %thunk, i32 0, i64 %a, i64 %b) 165 unreachable 166ret: 167 ret void 168} 169 170; Property Read 171; CHECK-LABEL: .long L{{.*}}-_propertyRead 172; CHECK-NEXT: .short 0 173; CHECK-NEXT: .short 2 174; CHECK-NEXT: .byte 1 175; CHECK-NEXT: .byte 8 176; CHECK-NEXT: .short {{[0-9]+}} 177; CHECK-NEXT: .long 0 178; CHECK-NEXT: .byte 1 179; CHECK-NEXT: .byte 8 180; CHECK-NEXT: .short {{[0-9]+}} 181; CHECK-NEXT: .long 0 182define i64 @propertyRead(i64* %obj) { 183entry: 184 %resolveRead = inttoptr i64 -559038737 to i8* 185 %result = call anyregcc i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 5, i32 15, i8* %resolveRead, i32 1, i64* %obj) 186 %add = add i64 %result, 3 187 ret i64 %add 188} 189 190; Property Write 191; CHECK-LABEL: .long L{{.*}}-_propertyWrite 192; CHECK-NEXT: .short 0 193; CHECK-NEXT: .short 2 194; CHECK-NEXT: .byte 1 195; CHECK-NEXT: .byte 8 196; CHECK-NEXT: .short {{[0-9]+}} 197; CHECK-NEXT: .long 0 198; CHECK-NEXT: .byte 1 199; CHECK-NEXT: .byte 8 200; CHECK-NEXT: .short {{[0-9]+}} 201; CHECK-NEXT: .long 0 202define void @propertyWrite(i64 %dummy1, i64* %obj, i64 %dummy2, i64 %a) { 203entry: 204 %resolveWrite = inttoptr i64 -559038737 to i8* 205 call anyregcc void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 6, i32 15, i8* %resolveWrite, i32 2, i64* %obj, i64 %a) 206 ret void 207} 208 209; Void JS Call 210; 211; 2 live variables in registers. 212; 213; CHECK-LABEL: .long L{{.*}}-_jsVoidCall 214; CHECK-NEXT: .short 0 215; CHECK-NEXT: .short 2 216; CHECK-NEXT: .byte 1 217; CHECK-NEXT: .byte 8 218; CHECK-NEXT: .short {{[0-9]+}} 219; CHECK-NEXT: .long 0 220; CHECK-NEXT: .byte 1 221; CHECK-NEXT: .byte 8 222; CHECK-NEXT: .short {{[0-9]+}} 223; CHECK-NEXT: .long 0 224define void @jsVoidCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) { 225entry: 226 %resolveCall = inttoptr i64 -559038737 to i8* 227 call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 7, i32 15, i8* %resolveCall, i32 2, i64* %obj, i64 %arg, i64 %l1, i64 %l2) 228 ret void 229} 230 231; i64 JS Call 232; 233; 2 live variables in registers. 234; 235; CHECK-LABEL: .long L{{.*}}-_jsIntCall 236; CHECK-NEXT: .short 0 237; CHECK-NEXT: .short 2 238; CHECK-NEXT: .byte 1 239; CHECK-NEXT: .byte 8 240; CHECK-NEXT: .short {{[0-9]+}} 241; CHECK-NEXT: .long 0 242; CHECK-NEXT: .byte 1 243; CHECK-NEXT: .byte 8 244; CHECK-NEXT: .short {{[0-9]+}} 245; CHECK-NEXT: .long 0 246define i64 @jsIntCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) { 247entry: 248 %resolveCall = inttoptr i64 -559038737 to i8* 249 %result = call i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 8, i32 15, i8* %resolveCall, i32 2, i64* %obj, i64 %arg, i64 %l1, i64 %l2) 250 %add = add i64 %result, 3 251 ret i64 %add 252} 253 254; Spilled stack map values. 255; 256; Verify 17 stack map entries. 257; 258; CHECK-LABEL: .long L{{.*}}-_spilledValue 259; CHECK-NEXT: .short 0 260; CHECK-NEXT: .short 17 261; 262; Check that at least one is a spilled entry from RBP. 263; Location: Indirect RBP + ... 264; CHECK: .byte 3 265; CHECK-NEXT: .byte 8 266; CHECK-NEXT: .short 6 267define 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) { 268entry: 269 call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 11, i32 15, 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) 270 ret void 271} 272 273; Spilled stack map values. 274; 275; Verify 17 stack map entries. 276; 277; CHECK-LABEL: .long L{{.*}}-_spilledStackMapValue 278; CHECK-NEXT: .short 0 279; CHECK-NEXT: .short 17 280; 281; Check that at least one is a spilled entry from RBP. 282; Location: Indirect RBP + ... 283; CHECK: .byte 3 284; CHECK-NEXT: .byte 8 285; CHECK-NEXT: .short 6 286define 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) { 287entry: 288 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) 289 ret void 290} 291 292; Spill a subregister stackmap operand. 293; 294; CHECK-LABEL: .long L{{.*}}-_spillSubReg 295; CHECK-NEXT: .short 0 296; 4 locations 297; CHECK-NEXT: .short 1 298; 299; Check that the subregister operand is a 4-byte spill. 300; Location: Indirect, 4-byte, RBP + ... 301; CHECK: .byte 3 302; CHECK-NEXT: .byte 4 303; CHECK-NEXT: .short 6 304define void @spillSubReg(i64 %arg) #0 { 305bb: 306 br i1 undef, label %bb1, label %bb2 307 308bb1: 309 unreachable 310 311bb2: 312 %tmp = load i64* inttoptr (i64 140685446136880 to i64*) 313 br i1 undef, label %bb16, label %bb17 314 315bb16: 316 unreachable 317 318bb17: 319 %tmp32 = trunc i64 %tmp to i32 320 br i1 undef, label %bb60, label %bb61 321 322bb60: 323 tail call void asm sideeffect "nop", "~{ax},~{bx},~{cx},~{dx},~{bp},~{si},~{di},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"() nounwind 324 tail call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 13, i32 5, i32 %tmp32) 325 unreachable 326 327bb61: 328 unreachable 329} 330 331; Map a single byte subregister. There is no DWARF register number, so 332; we expect the register to be encoded with the proper size and spill offset. We don't know which 333; 334; CHECK-LABEL: .long L{{.*}}-_subRegOffset 335; CHECK-NEXT: .short 0 336; 2 locations 337; CHECK-NEXT: .short 2 338; 339; Check that the subregister operands are 1-byte spills. 340; Location 0: Register, 4-byte, AL 341; CHECK-NEXT: .byte 1 342; CHECK-NEXT: .byte 1 343; CHECK-NEXT: .short 0 344; CHECK-NEXT: .long 0 345; 346; Location 1: Register, 4-byte, BL 347; CHECK-NEXT: .byte 1 348; CHECK-NEXT: .byte 1 349; CHECK-NEXT: .short 3 350; CHECK-NEXT: .long 0 351define void @subRegOffset(i16 %arg) { 352 %v = mul i16 %arg, 5 353 %a0 = trunc i16 %v to i8 354 tail call void asm sideeffect "nop", "~{bx}"() nounwind 355 %arghi = lshr i16 %v, 8 356 %a1 = trunc i16 %arghi to i8 357 tail call void asm sideeffect "nop", "~{cx},~{dx},~{bp},~{si},~{di},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"() nounwind 358 tail call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 14, i32 5, i8 %a0, i8 %a1) 359 ret void 360} 361 362; Map a constant value. 363; 364; CHECK-LABEL: .long L{{.*}}-_liveConstant 365; CHECK-NEXT: .short 0 366; 1 location 367; CHECK-NEXT: .short 1 368; Loc 0: SmallConstant 369; CHECK-NEXT: .byte 4 370; CHECK-NEXT: .byte 8 371; CHECK-NEXT: .short 0 372; CHECK-NEXT: .long 33 373 374define void @liveConstant() { 375 tail call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 15, i32 5, i32 33) 376 ret void 377} 378 379; Directly map an alloca's address. 380; 381; Callsite 16 382; CHECK-LABEL: .long L{{.*}}-_directFrameIdx 383; CHECK-NEXT: .short 0 384; 1 location 385; CHECK-NEXT: .short 1 386; Loc 0: Direct RBP - ofs 387; CHECK-NEXT: .byte 2 388; CHECK-NEXT: .byte 8 389; CHECK-NEXT: .short 6 390; CHECK-NEXT: .long 391 392; Callsite 17 393; CHECK-LABEL: .long L{{.*}}-_directFrameIdx 394; CHECK-NEXT: .short 0 395; 2 locations 396; CHECK-NEXT: .short 2 397; Loc 0: Direct RBP - ofs 398; CHECK-NEXT: .byte 2 399; CHECK-NEXT: .byte 8 400; CHECK-NEXT: .short 6 401; CHECK-NEXT: .long 402; Loc 1: Direct RBP - ofs 403; CHECK-NEXT: .byte 2 404; CHECK-NEXT: .byte 8 405; CHECK-NEXT: .short 6 406; CHECK-NEXT: .long 407define void @directFrameIdx() { 408entry: 409 %metadata1 = alloca i64, i32 3, align 8 410 store i64 11, i64* %metadata1 411 store i64 12, i64* %metadata1 412 store i64 13, i64* %metadata1 413 call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 16, i32 0, i64* %metadata1) 414 %metadata2 = alloca i8, i32 4, align 8 415 %metadata3 = alloca i16, i32 4, align 8 416 call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 17, i32 5, i8* null, i32 0, i8* %metadata2, i16* %metadata3) 417 ret void 418} 419 420; Test a 64-bit ID. 421; 422; CHECK: .quad 4294967295 423; CHECK-LABEL: .long L{{.*}}-_longid 424; CHECK: .quad 4294967296 425; CHECK-LABEL: .long L{{.*}}-_longid 426; CHECK: .quad 9223372036854775807 427; CHECK-LABEL: .long L{{.*}}-_longid 428; CHECK: .quad -1 429; CHECK-LABEL: .long L{{.*}}-_longid 430define void @longid() { 431entry: 432 tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 4294967295, i32 0, i8* null, i32 0) 433 tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 4294967296, i32 0, i8* null, i32 0) 434 tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 9223372036854775807, i32 0, i8* null, i32 0) 435 tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 -1, i32 0, i8* null, i32 0) 436 ret void 437} 438 439declare void @llvm.experimental.stackmap(i64, i32, ...) 440declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...) 441declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...) 442