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 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 2 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 spilledStackMapValue 83; CHECK-NEXT: .quad 224 84; CHECK-NEXT: .quad 1 85; CHECK-NEXT: .quad liveConstant 86; CHECK-NEXT: .quad 64 87; CHECK-NEXT: .quad 1 88; CHECK-NEXT: .quad clobberLR 89; CHECK-NEXT: .quad 208 90; CHECK-NEXT: .quad 1 91 92; Num LargeConstants 93; CHECK-NEXT: .quad 4294967295 94; CHECK-NEXT: .quad 4294967296 95 96; Constant arguments 97; 98; CHECK-NEXT: .quad 1 99; CHECK-NEXT: .long .L{{.*}}-.L[[constantargs_BEGIN]] 100; CHECK-NEXT: .short 0 101; CHECK-NEXT: .short 4 102; SmallConstant 103; CHECK-NEXT: .byte 4 104; CHECK-NEXT: .byte 0 105; CHECK-NEXT: .short 8 106; CHECK-NEXT: .short 0 107; CHECK-NEXT: .short 0 108; CHECK-NEXT: .long 65535 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 65536 116; SmallConstant 117; CHECK-NEXT: .byte 5 118; CHECK-NEXT: .byte 0 119; CHECK-NEXT: .short 8 120; CHECK-NEXT: .short 0 121; CHECK-NEXT: .short 0 122; CHECK-NEXT: .long 0 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 1 130 131define void @constantargs() { 132entry: 133 %0 = inttoptr i64 244837814094590 to i8* 134 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) 135 ret void 136} 137 138; Inline OSR Exit 139; 140; CHECK: .long .L{{.*}}-.L[[osrinline_BEGIN]] 141; CHECK-NEXT: .short 0 142; CHECK-NEXT: .short 2 143; CHECK-NEXT: .byte 1 144; CHECK-NEXT: .byte 0 145; CHECK-NEXT: .short 8 146; CHECK-NEXT: .short {{[0-9]+}} 147; CHECK-NEXT: .short 0 148; CHECK-NEXT: .long 0 149; CHECK-NEXT: .byte 1 150; CHECK-NEXT: .byte 0 151; CHECK-NEXT: .short 8 152; CHECK-NEXT: .short {{[0-9]+}} 153; CHECK-NEXT: .short 0 154; CHECK-NEXT: .long 0 155define void @osrinline(i64 %a, i64 %b) { 156entry: 157 ; Runtime void->void call. 158 call void inttoptr (i64 244837814094590 to void ()*)() 159 ; Followed by inline OSR patchpoint with 12-byte shadow and 2 live vars. 160 call void (i64, i32, ...) @llvm.experimental.stackmap(i64 3, i32 12, i64 %a, i64 %b) 161 ret void 162} 163 164; Cold OSR Exit 165; 166; 2 live variables in register. 167; 168; CHECK: .long .L{{.*}}-.L[[osrcold_BEGIN]] 169; CHECK-NEXT: .short 0 170; CHECK-NEXT: .short 2 171; CHECK-NEXT: .byte 1 172; CHECK-NEXT: .byte 0 173; CHECK-NEXT: .short 8 174; CHECK-NEXT: .short {{[0-9]+}} 175; CHECK-NEXT: .short 0 176; CHECK-NEXT: .long 0 177; CHECK-NEXT: .byte 1 178; CHECK-NEXT: .byte 0 179; CHECK-NEXT: .short 8 180; CHECK-NEXT: .short {{[0-9]+}} 181; CHECK-NEXT: .short 0 182; CHECK-NEXT: .long 0 183define void @osrcold(i64 %a, i64 %b) { 184entry: 185 %test = icmp slt i64 %a, %b 186 br i1 %test, label %ret, label %cold 187cold: 188 ; OSR patchpoint with 12-byte nop-slide and 2 live vars. 189 %thunk = inttoptr i64 244837814094590 to i8* 190 call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 4, i32 40, i8* %thunk, i32 0, i64 %a, i64 %b) 191 unreachable 192ret: 193 ret void 194} 195 196; Property Read 197; CHECK: .long .L{{.*}}-.L[[propertyRead_BEGIN]] 198; CHECK-NEXT: .short 0 199; CHECK-NEXT: .short 0 200; 201; FIXME: There are currently no stackmap entries. After moving to 202; AnyRegCC, we will have entries for the object and return value. 203define i64 @propertyRead(i64* %obj) { 204entry: 205 %resolveRead = inttoptr i64 244837814094590 to i8* 206 %result = call i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 5, i32 40, i8* %resolveRead, i32 1, i64* %obj) 207 %add = add i64 %result, 3 208 ret i64 %add 209} 210 211; Property Write 212; CHECK: .long .L{{.*}}-.L[[propertyWrite_BEGIN]] 213; CHECK-NEXT: .short 0 214; CHECK-NEXT: .short 2 215; CHECK-NEXT: .byte 1 216; CHECK-NEXT: .byte 0 217; CHECK-NEXT: .short 8 218; CHECK-NEXT: .short {{[0-9]+}} 219; CHECK-NEXT: .short 0 220; CHECK-NEXT: .long 0 221; CHECK-NEXT: .byte 1 222; CHECK-NEXT: .byte 0 223; CHECK-NEXT: .short 8 224; CHECK-NEXT: .short {{[0-9]+}} 225; CHECK-NEXT: .short 0 226; CHECK-NEXT: .long 0 227define void @propertyWrite(i64 %dummy1, i64* %obj, i64 %dummy2, i64 %a) { 228entry: 229 %resolveWrite = inttoptr i64 244837814094590 to i8* 230 call anyregcc void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 6, i32 40, i8* %resolveWrite, i32 2, i64* %obj, i64 %a) 231 ret void 232} 233 234; Void JS Call 235; 236; 2 live variables in registers. 237; 238; CHECK: .long .L{{.*}}-.L[[jsVoidCall_BEGIN]] 239; CHECK-NEXT: .short 0 240; CHECK-NEXT: .short 2 241; CHECK-NEXT: .byte 1 242; CHECK-NEXT: .byte 0 243; CHECK-NEXT: .short 8 244; CHECK-NEXT: .short {{[0-9]+}} 245; CHECK-NEXT: .short 0 246; CHECK-NEXT: .long 0 247; CHECK-NEXT: .byte 1 248; CHECK-NEXT: .byte 0 249; CHECK-NEXT: .short 8 250; CHECK-NEXT: .short {{[0-9]+}} 251; CHECK-NEXT: .short 0 252; CHECK-NEXT: .long 0 253define void @jsVoidCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) { 254entry: 255 %resolveCall = inttoptr i64 244837814094590 to i8* 256 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) 257 ret void 258} 259 260; i64 JS Call 261; 262; 2 live variables in registers. 263; 264; CHECK: .long .L{{.*}}-.L[[jsIntCall_BEGIN]] 265; CHECK-NEXT: .short 0 266; CHECK-NEXT: .short 2 267; CHECK-NEXT: .byte 1 268; CHECK-NEXT: .byte 0 269; CHECK-NEXT: .short 8 270; CHECK-NEXT: .short {{[0-9]+}} 271; CHECK-NEXT: .short 0 272; CHECK-NEXT: .long 0 273; CHECK-NEXT: .byte 1 274; CHECK-NEXT: .byte 0 275; CHECK-NEXT: .short 8 276; CHECK-NEXT: .short {{[0-9]+}} 277; CHECK-NEXT: .short 0 278; CHECK-NEXT: .long 0 279define i64 @jsIntCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) { 280entry: 281 %resolveCall = inttoptr i64 244837814094590 to i8* 282 %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) 283 %add = add i64 %result, 3 284 ret i64 %add 285} 286 287; Spilled stack map values. 288; 289; Verify 28 stack map entries. 290; 291; CHECK: .long .L{{.*}}-.L[[spilledValue_BEGIN]] 292; CHECK-NEXT: .short 0 293; CHECK-NEXT: .short 28 294; 295; Check that at least one is a spilled entry from r31. 296; Location: Indirect FP + ... 297; CHECK: .byte 3 298; CHECK-NEXT: .byte 0 299; CHECK-NEXT: .short 300; CHECK-NEXT: .short 31 301; CHECK-NEXT: .short 0 302; CHECK-NEXT: .long 303define 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) { 304entry: 305 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) 306 ret void 307} 308 309; Spilled stack map values. 310; 311; Verify 30 stack map entries. 312; 313; CHECK: .long .L{{.*}}-.L[[spilledStackMapValue_BEGIN]] 314; CHECK-NEXT: .short 0 315; CHECK-NEXT: .short 30 316; 317; Check that at least one is a spilled entry from r31. 318; Location: Indirect FP + ... 319; CHECK: .byte 3 320; CHECK-NEXT: .byte 0 321; CHECK-NEXT: .short 322; CHECK-NEXT: .short 31 323; CHECK-NEXT: .short 0 324; CHECK-NEXT: .long 325define 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) { 326entry: 327 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) 328 ret void 329} 330 331 332; Map a constant value. 333; 334; CHECK: .long .L{{.*}}-.L[[liveConstant_BEGIN]] 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 0 341; CHECK-NEXT: .short 8 342; CHECK-NEXT: .short 0 343; CHECK-NEXT: .short 0 344; CHECK-NEXT: .long 33 345 346define void @liveConstant() { 347 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 15, i32 8, i32 33) 348 ret void 349} 350 351; Map a value when LR is the only free register. 352; 353; CHECK: .long .L{{.*}}-.L[[clobberLR_BEGIN]] 354; CHECK-NEXT: .short 0 355; 1 location 356; CHECK-NEXT: .short 1 357; Loc 0: Indirect FP (r31) - offset 358; CHECK-NEXT: .byte 3 359; CHECK-NEXT: .byte 0 360; CHECK-NEXT: .short 4 361; CHECK-NEXT: .short 31 362; CHECK-NEXT: .short 0 363; CHECK-NEXT: .long {{[0-9]+}} 364define void @clobberLR(i32 %a) { 365 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 366 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 16, i32 8, i32 %a) 367 ret void 368} 369 370declare void @llvm.experimental.stackmap(i64, i32, ...) 371declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...) 372declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...) 373