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: spilledStackMapValue: 35; CHECK: {{^}}.L[[spilledStackMapValue_BEGIN:.*]]:{{$}} 36 37; CHECK-LABEL: liveConstant: 38; CHECK: {{^}}.L[[liveConstant_BEGIN:.*]]:{{$}} 39 40; CHECK-LABEL: clobberLR: 41; CHECK: {{^}}.L[[clobberLR_BEGIN:.*]]:{{$}} 42 43; CHECK-LABEL: floats: 44; CHECK: {{^}}.L[[floats_BEGIN:.*]]:{{$}} 45 46 47; CHECK-LABEL: .section .llvm_stackmaps 48; CHECK-NEXT: __LLVM_StackMaps: 49; Header 50; CHECK-NEXT: .byte 3 51; CHECK-NEXT: .byte 0 52; CHECK-NEXT: .short 0 53; Num Functions 54; CHECK-NEXT: .long 12 55; Num LargeConstants 56; CHECK-NEXT: .long 3 57; Num Callsites 58; CHECK-NEXT: .long 12 59 60; Functions and stack size 61; CHECK-NEXT: .quad constantargs 62; CHECK-NEXT: .quad 128 63; CHECK-NEXT: .quad 1 64; CHECK-NEXT: .quad osrinline 65; CHECK-NEXT: .quad 144 66; CHECK-NEXT: .quad 1 67; CHECK-NEXT: .quad osrcold 68; CHECK-NEXT: .quad 128 69; CHECK-NEXT: .quad 1 70; CHECK-NEXT: .quad propertyRead 71; CHECK-NEXT: .quad 128 72; CHECK-NEXT: .quad 1 73; CHECK-NEXT: .quad propertyWrite 74; CHECK-NEXT: .quad 128 75; CHECK-NEXT: .quad 1 76; CHECK-NEXT: .quad jsVoidCall 77; CHECK-NEXT: .quad 128 78; CHECK-NEXT: .quad 1 79; CHECK-NEXT: .quad jsIntCall 80; CHECK-NEXT: .quad 128 81; CHECK-NEXT: .quad 1 82; CHECK-NEXT: .quad spilledValue 83; CHECK-NEXT: .quad 304 84; CHECK-NEXT: .quad 1 85; CHECK-NEXT: .quad spilledStackMapValue 86; CHECK-NEXT: .quad 224 87; CHECK-NEXT: .quad 1 88; CHECK-NEXT: .quad liveConstant 89; CHECK-NEXT: .quad 64 90; CHECK-NEXT: .quad 1 91; CHECK-NEXT: .quad clobberLR 92; CHECK-NEXT: .quad 208 93; CHECK-NEXT: .quad 1 94; CHECK-NEXT: .quad floats 95; CHECK-NEXT: .quad 80 96; CHECK-NEXT: .quad 1 97 98; Num LargeConstants 99; CHECK-NEXT: .quad 4294967295 100; CHECK-NEXT: .quad 4294967296 101; CHECK-NEXT: .quad 4294967297 102 103; Constant arguments 104; 105; CHECK-NEXT: .quad 1 106; CHECK-NEXT: .long .L{{.*}}-.L[[constantargs_BEGIN]] 107; CHECK-NEXT: .short 0 108; CHECK-NEXT: .short 6 109; SmallConstant 110; CHECK-NEXT: .byte 4 111; CHECK-NEXT: .byte 0 112; CHECK-NEXT: .short 8 113; CHECK-NEXT: .short 0 114; CHECK-NEXT: .short 0 115; CHECK-NEXT: .long 65535 116; SmallConstant 117; CHECK-NEXT: .byte 4 118; CHECK-NEXT: .byte 0 119; CHECK-NEXT: .short 8 120; CHECK-NEXT: .short 0 121; CHECK-NEXT: .short 0 122; CHECK-NEXT: .long 65536 123; LargeConstant at index 0 124; CHECK-NEXT: .byte 5 125; CHECK-NEXT: .byte 0 126; CHECK-NEXT: .short 8 127; CHECK-NEXT: .short 0 128; CHECK-NEXT: .short 0 129; CHECK-NEXT: .long 0 130; LargeConstant at index 1 131; CHECK-NEXT: .byte 5 132; CHECK-NEXT: .byte 0 133; CHECK-NEXT: .short 8 134; CHECK-NEXT: .short 0 135; CHECK-NEXT: .short 0 136; CHECK-NEXT: .long 1 137; SmallConstant 138; CHECK-NEXT: .byte 4 139; CHECK-NEXT: .byte 0 140; CHECK-NEXT: .short 8 141; CHECK-NEXT: .short 0 142; CHECK-NEXT: .short 0 143; CHECK-NEXT: .long 66 144; LargeConstant at index 2 145; CHECK-NEXT: .byte 5 146; CHECK-NEXT: .byte 0 147; CHECK-NEXT: .short 8 148; CHECK-NEXT: .short 0 149; CHECK-NEXT: .short 0 150; CHECK-NEXT: .long 2 151 152define void @constantargs() { 153entry: 154 %0 = inttoptr i64 244837814094590 to i8* 155 tail call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 1, i32 40, i8* %0, i32 0, i64 65535, i64 65536, i64 4294967295, i64 4294967296, i128 66, i128 4294967297) 156 ret void 157} 158 159; Inline OSR Exit 160; 161; CHECK: .long .L{{.*}}-.L[[osrinline_BEGIN]] 162; CHECK-NEXT: .short 0 163; CHECK-NEXT: .short 2 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 170; CHECK-NEXT: .byte 1 171; CHECK-NEXT: .byte 0 172; CHECK-NEXT: .short 8 173; CHECK-NEXT: .short {{[0-9]+}} 174; CHECK-NEXT: .short 0 175; CHECK-NEXT: .long 0 176define void @osrinline(i64 %a, i64 %b) { 177entry: 178 ; Runtime void->void call. 179 call void inttoptr (i64 244837814094590 to void ()*)() 180 ; Followed by inline OSR patchpoint with 12-byte shadow and 2 live vars. 181 call void (i64, i32, ...) @llvm.experimental.stackmap(i64 3, i32 12, i64 %a, i64 %b) 182 ret void 183} 184 185; Cold OSR Exit 186; 187; 2 live variables in register. 188; 189; CHECK: .long .L{{.*}}-.L[[osrcold_BEGIN]] 190; CHECK-NEXT: .short 0 191; CHECK-NEXT: .short 2 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 198; CHECK-NEXT: .byte 1 199; CHECK-NEXT: .byte 0 200; CHECK-NEXT: .short 8 201; CHECK-NEXT: .short {{[0-9]+}} 202; CHECK-NEXT: .short 0 203; CHECK-NEXT: .long 0 204define void @osrcold(i64 %a, i64 %b) { 205entry: 206 %test = icmp slt i64 %a, %b 207 br i1 %test, label %ret, label %cold 208cold: 209 ; OSR patchpoint with 12-byte nop-slide and 2 live vars. 210 %thunk = inttoptr i64 244837814094590 to i8* 211 call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 4, i32 40, i8* %thunk, i32 0, i64 %a, i64 %b) 212 unreachable 213ret: 214 ret void 215} 216 217; Property Read 218; CHECK: .long .L{{.*}}-.L[[propertyRead_BEGIN]] 219; CHECK-NEXT: .short 0 220; CHECK-NEXT: .short 0 221; 222; FIXME: There are currently no stackmap entries. After moving to 223; AnyRegCC, we will have entries for the object and return value. 224define i64 @propertyRead(i64* %obj) { 225entry: 226 %resolveRead = inttoptr i64 244837814094590 to i8* 227 %result = call i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 5, i32 40, i8* %resolveRead, i32 1, i64* %obj) 228 %add = add i64 %result, 3 229 ret i64 %add 230} 231 232; Property Write 233; CHECK: .long .L{{.*}}-.L[[propertyWrite_BEGIN]] 234; CHECK-NEXT: .short 0 235; CHECK-NEXT: .short 2 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 242; CHECK-NEXT: .byte 1 243; CHECK-NEXT: .byte 0 244; CHECK-NEXT: .short 8 245; CHECK-NEXT: .short {{[0-9]+}} 246; CHECK-NEXT: .short 0 247; CHECK-NEXT: .long 0 248define void @propertyWrite(i64 %dummy1, i64* %obj, i64 %dummy2, i64 %a) { 249entry: 250 %resolveWrite = inttoptr i64 244837814094590 to i8* 251 call anyregcc void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 6, i32 40, i8* %resolveWrite, i32 2, i64* %obj, i64 %a) 252 ret void 253} 254 255; Void JS Call 256; 257; 2 live variables in registers. 258; 259; CHECK: .long .L{{.*}}-.L[[jsVoidCall_BEGIN]] 260; CHECK-NEXT: .short 0 261; CHECK-NEXT: .short 2 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 268; CHECK-NEXT: .byte 1 269; CHECK-NEXT: .byte 0 270; CHECK-NEXT: .short 8 271; CHECK-NEXT: .short {{[0-9]+}} 272; CHECK-NEXT: .short 0 273; CHECK-NEXT: .long 0 274define void @jsVoidCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) { 275entry: 276 %resolveCall = inttoptr i64 244837814094590 to i8* 277 call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 7, i32 40, i8* %resolveCall, i32 2, i64* %obj, i64 %arg, i64 %l1, i64 %l2) 278 ret void 279} 280 281; i64 JS Call 282; 283; 2 live variables in registers. 284; 285; CHECK: .long .L{{.*}}-.L[[jsIntCall_BEGIN]] 286; CHECK-NEXT: .short 0 287; CHECK-NEXT: .short 2 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 294; CHECK-NEXT: .byte 1 295; CHECK-NEXT: .byte 0 296; CHECK-NEXT: .short 8 297; CHECK-NEXT: .short {{[0-9]+}} 298; CHECK-NEXT: .short 0 299; CHECK-NEXT: .long 0 300define i64 @jsIntCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) { 301entry: 302 %resolveCall = inttoptr i64 244837814094590 to i8* 303 %result = call i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 8, i32 40, i8* %resolveCall, i32 2, i64* %obj, i64 %arg, i64 %l1, i64 %l2) 304 %add = add i64 %result, 3 305 ret i64 %add 306} 307 308; Spilled stack map values. 309; 310; Verify 28 stack map entries. 311; 312; CHECK: .long .L{{.*}}-.L[[spilledValue_BEGIN]] 313; CHECK-NEXT: .short 0 314; CHECK-NEXT: .short 28 315; 316; Check that at least one is a spilled entry from r31. 317; Location: Indirect FP + ... 318; CHECK: .byte 3 319; CHECK-NEXT: .byte 0 320; CHECK-NEXT: .short 321; CHECK-NEXT: .short 31 322; CHECK-NEXT: .short 0 323; CHECK-NEXT: .long 324define 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) { 325entry: 326 call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 11, i32 40, 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, i64 %l17, i64 %l18, i64 %l19, i64 %l20, i64 %l21, i64 %l22, i64 %l23, i64 %l24, i64 %l25, i64 %l26, i64 %l27) 327 ret void 328} 329 330; Spilled stack map values. 331; 332; Verify 30 stack map entries. 333; 334; CHECK: .long .L{{.*}}-.L[[spilledStackMapValue_BEGIN]] 335; CHECK-NEXT: .short 0 336; CHECK-NEXT: .short 30 337; 338; Check that at least one is a spilled entry from r31. 339; Location: Indirect FP + ... 340; CHECK: .byte 3 341; CHECK-NEXT: .byte 0 342; CHECK-NEXT: .short 343; CHECK-NEXT: .short 31 344; CHECK-NEXT: .short 0 345; CHECK-NEXT: .long 346define 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, i64 %l17, i64 %l18, i64 %l19, i64 %l20, i64 %l21, i64 %l22, i64 %l23, i64 %l24, i64 %l25, i64 %l26, i64 %l27, i64 %l28, i64 %l29) { 347entry: 348 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, i64 %l17, i64 %l18, i64 %l19, i64 %l20, i64 %l21, i64 %l22, i64 %l23, i64 %l24, i64 %l25, i64 %l26, i64 %l27, i64 %l28, i64 %l29) 349 ret void 350} 351 352 353; Map a constant value. 354; 355; CHECK: .long .L{{.*}}-.L[[liveConstant_BEGIN]] 356; CHECK-NEXT: .short 0 357; 1 location 358; CHECK-NEXT: .short 1 359; Loc 0: SmallConstant 360; CHECK-NEXT: .byte 4 361; CHECK-NEXT: .byte 0 362; CHECK-NEXT: .short 8 363; CHECK-NEXT: .short 0 364; CHECK-NEXT: .short 0 365; CHECK-NEXT: .long 33 366 367define void @liveConstant() { 368 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 15, i32 8, i32 33) 369 ret void 370} 371 372; Map a value when LR is the only free register. 373; 374; CHECK: .long .L{{.*}}-.L[[clobberLR_BEGIN]] 375; CHECK-NEXT: .short 0 376; 1 location 377; CHECK-NEXT: .short 1 378; Loc 0: Indirect FP (r31) - offset 379; CHECK-NEXT: .byte 3 380; CHECK-NEXT: .byte 0 381; CHECK-NEXT: .short 4 382; CHECK-NEXT: .short 31 383; CHECK-NEXT: .short 0 384; CHECK-NEXT: .long {{[0-9]+}} 385define void @clobberLR(i32 %a) { 386 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 387 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 16, i32 8, i32 %a) 388 ret void 389} 390 391; CHECK: .long .L{{.*}}-.L[[floats_BEGIN]] 392; CHECK-NEXT: .short 0 393; Num Locations 394; CHECK-NEXT: .short 6 395; Loc 0: constant float stored to FP register 396; CHECK-NEXT: .byte 1 397; CHECK-NEXT: .byte 0 398; CHECK-NEXT: .short 8 399; CHECK-NEXT: .short {{.*}} 400; CHECK-NEXT: .short 0 401; CHECK-NEXT: .long 0 402; Loc 0: constant double stored to FP register 403; CHECK-NEXT: .byte 1 404; CHECK-NEXT: .byte 0 405; CHECK-NEXT: .short 8 406; CHECK-NEXT: .short {{.*}} 407; CHECK-NEXT: .short 0 408; CHECK-NEXT: .long 0 409; Loc 1: float value in FP register 410; CHECK-NEXT: .byte 1 411; CHECK-NEXT: .byte 0 412; CHECK-NEXT: .short 8 413; CHECK-NEXT: .short {{.*}} 414; CHECK-NEXT: .short 0 415; CHECK-NEXT: .long 0 416; Loc 2: double value in FP register 417; CHECK-NEXT: .byte 1 418; CHECK-NEXT: .byte 0 419; CHECK-NEXT: .short 8 420; CHECK-NEXT: .short {{.*}} 421; CHECK-NEXT: .short 0 422; CHECK-NEXT: .long 0 423; Loc 3: float on stack 424; CHECK-NEXT: .byte 2 425; CHECK-NEXT: .byte 0 426; CHECK-NEXT: .short 8 427; CHECK-NEXT: .short {{.*}} 428; CHECK-NEXT: .short 0 429; CHECK-NEXT: .long {{.*}} 430; Loc 4: double on stack 431; CHECK-NEXT: .byte 2 432; CHECK-NEXT: .byte 0 433; CHECK-NEXT: .short 8 434; CHECK-NEXT: .short {{.*}} 435; CHECK-NEXT: .short 0 436; CHECK-NEXT: .long {{.*}} 437define void @floats(float %f, double %g) { 438 %ff = alloca float 439 %gg = alloca double 440 call void (i64, i32, ...) @llvm.experimental.stackmap(i64 888, i32 0, float 1.25, 441 double 1.5, float %f, double %g, float* %ff, double* %gg) 442 ret void 443} 444 445declare void @llvm.experimental.stackmap(i64, i32, ...) 446declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...) 447declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...) 448