1; RUN: llc -verify-machineinstrs < %s | FileCheck %s 2; 3; Note: Print verbose stackmaps using -debug-only=stackmaps. 4 5; We are not getting the correct stack alignment when cross compiling for arm64. 6; So specify a datalayout here. 7target datalayout = "E-m:e-i64:64-n32:64" 8target triple = "powerpc64-unknown-linux-gnu" 9 10; CHECK-LABEL: constantargs: 11; CHECK: {{^}}.L[[constantargs_BEGIN:.*]]:{{$}} 12 13; CHECK-LABEL: osrinline: 14; CHECK: {{^}}.L[[osrinline_BEGIN:.*]]:{{$}} 15 16; CHECK-LABEL: osrcold: 17; CHECK: {{^}}.L[[osrcold_BEGIN:.*]]:{{$}} 18 19; CHECK-LABEL: propertyRead: 20; CHECK: {{^}}.L[[propertyRead_BEGIN:.*]]:{{$}} 21 22; CHECK-LABEL: propertyWrite: 23; CHECK: {{^}}.L[[propertyWrite_BEGIN:.*]]:{{$}} 24 25; CHECK-LABEL: jsVoidCall: 26; CHECK: {{^}}.L[[jsVoidCall_BEGIN:.*]]:{{$}} 27 28; CHECK-LABEL: jsIntCall: 29; CHECK: {{^}}.L[[jsIntCall_BEGIN:.*]]:{{$}} 30 31; CHECK-LABEL: spilledValue: 32; CHECK: {{^}}.L[[spilledValue_BEGIN:.*]]:{{$}} 33 34; CHECK-LABEL: liveConstant: 35; CHECK: {{^}}.L[[liveConstant_BEGIN:.*]]:{{$}} 36 37; CHECK-LABEL: clobberLR: 38; CHECK: {{^}}.L[[clobberLR_BEGIN:.*]]:{{$}} 39 40; CHECK-LABEL: floats: 41; CHECK: {{^}}.L[[floats_BEGIN:.*]]:{{$}} 42 43 44; CHECK-LABEL: .section .llvm_stackmaps 45; CHECK-NEXT: __LLVM_StackMaps: 46; Header 47; CHECK-NEXT: .byte 3 48; CHECK-NEXT: .byte 0 49; CHECK-NEXT: .short 0 50; Num Functions 51; CHECK-NEXT: .long 11 52; Num LargeConstants 53; CHECK-NEXT: .long 3 54; Num Callsites 55; CHECK-NEXT: .long 11 56 57; Functions and stack size 58; CHECK-NEXT: .quad constantargs 59; CHECK-NEXT: .quad 128 60; CHECK-NEXT: .quad 1 61; CHECK-NEXT: .quad osrinline 62; CHECK-NEXT: .quad 144 63; CHECK-NEXT: .quad 1 64; CHECK-NEXT: .quad osrcold 65; CHECK-NEXT: .quad 128 66; CHECK-NEXT: .quad 1 67; CHECK-NEXT: .quad propertyRead 68; CHECK-NEXT: .quad 128 69; CHECK-NEXT: .quad 1 70; CHECK-NEXT: .quad propertyWrite 71; CHECK-NEXT: .quad 128 72; CHECK-NEXT: .quad 1 73; CHECK-NEXT: .quad jsVoidCall 74; CHECK-NEXT: .quad 128 75; CHECK-NEXT: .quad 1 76; CHECK-NEXT: .quad jsIntCall 77; CHECK-NEXT: .quad 128 78; CHECK-NEXT: .quad 1 79; CHECK-NEXT: .quad spilledValue 80; CHECK-NEXT: .quad 304 81; CHECK-NEXT: .quad 1 82; CHECK-NEXT: .quad liveConstant 83; CHECK-NEXT: .quad 64 84; CHECK-NEXT: .quad 1 85; CHECK-NEXT: .quad clobberLR 86; CHECK-NEXT: .quad 208 87; CHECK-NEXT: .quad 1 88; CHECK-NEXT: .quad floats 89; CHECK-NEXT: .quad 80 90; CHECK-NEXT: .quad 1 91 92; Num LargeConstants 93; CHECK-NEXT: .quad 4294967295 94; CHECK-NEXT: .quad 4294967296 95; CHECK-NEXT: .quad 4294967297 96 97; Constant arguments 98; 99; CHECK-NEXT: .quad 1 100; CHECK-NEXT: .long .L{{.*}}-.L[[constantargs_BEGIN]] 101; CHECK-NEXT: .short 0 102; CHECK-NEXT: .short 6 103; SmallConstant 104; CHECK-NEXT: .byte 4 105; CHECK-NEXT: .byte 0 106; CHECK-NEXT: .short 8 107; CHECK-NEXT: .short 0 108; CHECK-NEXT: .short 0 109; CHECK-NEXT: .long 65535 110; SmallConstant 111; CHECK-NEXT: .byte 4 112; CHECK-NEXT: .byte 0 113; CHECK-NEXT: .short 8 114; CHECK-NEXT: .short 0 115; CHECK-NEXT: .short 0 116; CHECK-NEXT: .long 65536 117; LargeConstant at index 0 118; CHECK-NEXT: .byte 5 119; CHECK-NEXT: .byte 0 120; CHECK-NEXT: .short 8 121; CHECK-NEXT: .short 0 122; CHECK-NEXT: .short 0 123; CHECK-NEXT: .long 0 124; LargeConstant at index 1 125; CHECK-NEXT: .byte 5 126; CHECK-NEXT: .byte 0 127; CHECK-NEXT: .short 8 128; CHECK-NEXT: .short 0 129; CHECK-NEXT: .short 0 130; CHECK-NEXT: .long 1 131; SmallConstant 132; CHECK-NEXT: .byte 4 133; CHECK-NEXT: .byte 0 134; CHECK-NEXT: .short 8 135; CHECK-NEXT: .short 0 136; CHECK-NEXT: .short 0 137; CHECK-NEXT: .long 66 138; LargeConstant at index 2 139; CHECK-NEXT: .byte 5 140; CHECK-NEXT: .byte 0 141; CHECK-NEXT: .short 8 142; CHECK-NEXT: .short 0 143; CHECK-NEXT: .short 0 144; CHECK-NEXT: .long 2 145 146define void @constantargs() { 147entry: 148 %0 = inttoptr i64 244837814094590 to ptr 149 tail call void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 1, i32 40, ptr %0, i32 0, i64 65535, i64 65536, i64 4294967295, i64 4294967296, i128 66, i128 4294967297) 150 ret void 151} 152 153; Inline OSR Exit 154; 155; CHECK: .long .L{{.*}}-.L[[osrinline_BEGIN]] 156; CHECK-NEXT: .short 0 157; CHECK-NEXT: .short 2 158; CHECK-NEXT: .byte 1 159; CHECK-NEXT: .byte 0 160; CHECK-NEXT: .short 8 161; CHECK-NEXT: .short {{[0-9]+}} 162; CHECK-NEXT: .short 0 163; CHECK-NEXT: .long 0 164; CHECK-NEXT: .byte 1 165; CHECK-NEXT: .byte 0 166; CHECK-NEXT: .short 8 167; CHECK-NEXT: .short {{[0-9]+}} 168; CHECK-NEXT: .short 0 169; CHECK-NEXT: .long 0 170define void @osrinline(i64 %a, i64 %b) { 171entry: 172 ; Runtime void->void call. 173 call void inttoptr (i64 244837814094590 to ptr)() 174 ; Followed by inline OSR patchpoint with 12-byte shadow and 2 live vars. 175 call void (i64, i32, ...) @llvm.experimental.stackmap(i64 3, i32 12, i64 %a, i64 %b) 176 ret void 177} 178 179; Cold OSR Exit 180; 181; 2 live variables in register. 182; 183; CHECK: .long .L{{.*}}-.L[[osrcold_BEGIN]] 184; CHECK-NEXT: .short 0 185; CHECK-NEXT: .short 2 186; CHECK-NEXT: .byte 1 187; CHECK-NEXT: .byte 0 188; CHECK-NEXT: .short 8 189; CHECK-NEXT: .short {{[0-9]+}} 190; CHECK-NEXT: .short 0 191; CHECK-NEXT: .long 0 192; CHECK-NEXT: .byte 1 193; CHECK-NEXT: .byte 0 194; CHECK-NEXT: .short 8 195; CHECK-NEXT: .short {{[0-9]+}} 196; CHECK-NEXT: .short 0 197; CHECK-NEXT: .long 0 198define void @osrcold(i64 %a, i64 %b) { 199entry: 200 %test = icmp slt i64 %a, %b 201 br i1 %test, label %ret, label %cold 202cold: 203 ; OSR patchpoint with 12-byte nop-slide and 2 live vars. 204 %thunk = inttoptr i64 244837814094590 to ptr 205 call void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 4, i32 40, ptr %thunk, i32 0, i64 %a, i64 %b) 206 unreachable 207ret: 208 ret void 209} 210 211; Property Read 212; CHECK: .long .L{{.*}}-.L[[propertyRead_BEGIN]] 213; CHECK-NEXT: .short 0 214; CHECK-NEXT: .short 0 215; 216; FIXME: There are currently no stackmap entries. After moving to 217; AnyRegCC, we will have entries for the object and return value. 218define i64 @propertyRead(ptr %obj) { 219entry: 220 %resolveRead = inttoptr i64 244837814094590 to ptr 221 %result = call i64 (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.i64(i64 5, i32 40, ptr %resolveRead, i32 1, ptr %obj) 222 %add = add i64 %result, 3 223 ret i64 %add 224} 225 226; Property Write 227; CHECK: .long .L{{.*}}-.L[[propertyWrite_BEGIN]] 228; CHECK-NEXT: .short 0 229; CHECK-NEXT: .short 2 230; CHECK-NEXT: .byte 1 231; CHECK-NEXT: .byte 0 232; CHECK-NEXT: .short 8 233; CHECK-NEXT: .short {{[0-9]+}} 234; CHECK-NEXT: .short 0 235; CHECK-NEXT: .long 0 236; CHECK-NEXT: .byte 1 237; CHECK-NEXT: .byte 0 238; CHECK-NEXT: .short 8 239; CHECK-NEXT: .short {{[0-9]+}} 240; CHECK-NEXT: .short 0 241; CHECK-NEXT: .long 0 242define void @propertyWrite(i64 %dummy1, ptr %obj, i64 %dummy2, i64 %a) { 243entry: 244 %resolveWrite = inttoptr i64 244837814094590 to ptr 245 call anyregcc void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 6, i32 40, ptr %resolveWrite, i32 2, ptr %obj, i64 %a) 246 ret void 247} 248 249; Void JS Call 250; 251; 2 live variables in registers. 252; 253; CHECK: .long .L{{.*}}-.L[[jsVoidCall_BEGIN]] 254; CHECK-NEXT: .short 0 255; CHECK-NEXT: .short 2 256; CHECK-NEXT: .byte 1 257; CHECK-NEXT: .byte 0 258; CHECK-NEXT: .short 8 259; CHECK-NEXT: .short {{[0-9]+}} 260; CHECK-NEXT: .short 0 261; CHECK-NEXT: .long 0 262; CHECK-NEXT: .byte 1 263; CHECK-NEXT: .byte 0 264; CHECK-NEXT: .short 8 265; CHECK-NEXT: .short {{[0-9]+}} 266; CHECK-NEXT: .short 0 267; CHECK-NEXT: .long 0 268define void @jsVoidCall(i64 %dummy1, ptr %obj, i64 %arg, i64 %l1, i64 %l2) { 269entry: 270 %resolveCall = inttoptr i64 244837814094590 to ptr 271 call void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 7, i32 40, ptr %resolveCall, i32 2, ptr %obj, i64 %arg, i64 %l1, i64 %l2) 272 ret void 273} 274 275; i64 JS Call 276; 277; 2 live variables in registers. 278; 279; CHECK: .long .L{{.*}}-.L[[jsIntCall_BEGIN]] 280; CHECK-NEXT: .short 0 281; CHECK-NEXT: .short 2 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 288; CHECK-NEXT: .byte 1 289; CHECK-NEXT: .byte 0 290; CHECK-NEXT: .short 8 291; CHECK-NEXT: .short {{[0-9]+}} 292; CHECK-NEXT: .short 0 293; CHECK-NEXT: .long 0 294define i64 @jsIntCall(i64 %dummy1, ptr %obj, i64 %arg, i64 %l1, i64 %l2) { 295entry: 296 %resolveCall = inttoptr i64 244837814094590 to ptr 297 %result = call i64 (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.i64(i64 8, i32 40, ptr %resolveCall, i32 2, ptr %obj, i64 %arg, i64 %l1, i64 %l2) 298 %add = add i64 %result, 3 299 ret i64 %add 300} 301 302; Spilled stack map values. 303; 304; Verify 28 stack map entries. 305; 306; CHECK: .long .L{{.*}}-.L[[spilledValue_BEGIN]] 307; CHECK-NEXT: .short 0 308; CHECK-NEXT: .short 28 309; 310; Check that at least one is a spilled entry from r31. 311; Location: Indirect FP + ... 312; CHECK: .byte 3 313; CHECK-NEXT: .byte 0 314; CHECK-NEXT: .short 315; CHECK-NEXT: .short 31 316; CHECK-NEXT: .short 0 317; CHECK-NEXT: .long 318define 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, i64 %l17, i64 %l18, i64 %l19, i64 %l20, i64 %l21, i64 %l22, i64 %l23, i64 %l24, i64 %l25, i64 %l26, i64 %l27) { 319entry: 320 call void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 11, i32 40, 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, i64 %l17, i64 %l18, i64 %l19, i64 %l20, i64 %l21, i64 %l22, i64 %l23, i64 %l24, i64 %l25, i64 %l26, i64 %l27) 321 ret void 322} 323 324; Map a constant value. 325; 326; CHECK: .long .L{{.*}}-.L[[liveConstant_BEGIN]] 327; CHECK-NEXT: .short 0 328; 1 location 329; CHECK-NEXT: .short 1 330; Loc 0: SmallConstant 331; CHECK-NEXT: .byte 4 332; CHECK-NEXT: .byte 0 333; CHECK-NEXT: .short 8 334; CHECK-NEXT: .short 0 335; CHECK-NEXT: .short 0 336; CHECK-NEXT: .long 33 337 338define void @liveConstant() { 339 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 15, i32 8, i32 33) 340 ret void 341} 342 343; Map a value when LR is the only free register. 344; 345; CHECK: .long .L{{.*}}-.L[[clobberLR_BEGIN]] 346; CHECK-NEXT: .short 0 347; 1 location 348; CHECK-NEXT: .short 1 349; Loc 0: Indirect FP (r31) - offset 350; CHECK-NEXT: .byte 3 351; CHECK-NEXT: .byte 0 352; CHECK-NEXT: .short 4 353; CHECK-NEXT: .short 31 354; CHECK-NEXT: .short 0 355; CHECK-NEXT: .long {{[0-9]+}} 356define void @clobberLR(i32 %a) { 357 tail call void asm sideeffect "nop", "~{r0},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{r14},~{r15},~{r16},~{r17},~{r18},~{r19},~{r20},~{r21},~{r22},~{r23},~{r24},~{r25},~{r26},~{r27},~{r28},~{r29},~{r30},~{r31}"() nounwind 358 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 16, i32 8, i32 %a) 359 ret void 360} 361 362; CHECK: .long .L{{.*}}-.L[[floats_BEGIN]] 363; CHECK-NEXT: .short 0 364; Num Locations 365; CHECK-NEXT: .short 6 366; Loc 0: constant float stored to FP register 367; CHECK-NEXT: .byte 1 368; CHECK-NEXT: .byte 0 369; CHECK-NEXT: .short 8 370; CHECK-NEXT: .short {{.*}} 371; CHECK-NEXT: .short 0 372; CHECK-NEXT: .long 0 373; Loc 0: constant double stored to FP register 374; CHECK-NEXT: .byte 1 375; CHECK-NEXT: .byte 0 376; CHECK-NEXT: .short 8 377; CHECK-NEXT: .short {{.*}} 378; CHECK-NEXT: .short 0 379; CHECK-NEXT: .long 0 380; Loc 1: float value in FP register 381; CHECK-NEXT: .byte 1 382; CHECK-NEXT: .byte 0 383; CHECK-NEXT: .short 8 384; CHECK-NEXT: .short {{.*}} 385; CHECK-NEXT: .short 0 386; CHECK-NEXT: .long 0 387; Loc 2: double value in FP register 388; CHECK-NEXT: .byte 1 389; CHECK-NEXT: .byte 0 390; CHECK-NEXT: .short 8 391; CHECK-NEXT: .short {{.*}} 392; CHECK-NEXT: .short 0 393; CHECK-NEXT: .long 0 394; Loc 3: float on stack 395; CHECK-NEXT: .byte 2 396; CHECK-NEXT: .byte 0 397; CHECK-NEXT: .short 8 398; CHECK-NEXT: .short {{.*}} 399; CHECK-NEXT: .short 0 400; CHECK-NEXT: .long {{.*}} 401; Loc 4: double on stack 402; CHECK-NEXT: .byte 2 403; CHECK-NEXT: .byte 0 404; CHECK-NEXT: .short 8 405; CHECK-NEXT: .short {{.*}} 406; CHECK-NEXT: .short 0 407; CHECK-NEXT: .long {{.*}} 408define void @floats(float %f, double %g) { 409 %ff = alloca float 410 %gg = alloca double 411 call void (i64, i32, ...) @llvm.experimental.stackmap(i64 888, i32 0, float 1.25, 412 double 1.5, float %f, double %g, ptr %ff, ptr %gg) 413 ret void 414} 415 416declare void @llvm.experimental.stackmap(i64, i32, ...) 417declare void @llvm.experimental.patchpoint.void(i64, i32, ptr, i32, ...) 418declare i64 @llvm.experimental.patchpoint.i64(i64, i32, ptr, i32, ...) 419