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