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