385 lines · plain
1; RUN: llc -mtriple=arm64-apple-darwin -mattr=+reserve-x18 < %s | FileCheck %s2; RUN: llc -mtriple=arm64-apple-darwin -mattr=+reserve-x18 -fast-isel -fast-isel-abort=1 < %s | FileCheck %s3;4; Note: Print verbose stackmaps using -debug-only=stackmaps.5 6; We are not getting the correct stack alignment when cross compiling for arm64.7; So specify a datalayout here.8target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"9 10; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps11; CHECK-NEXT: __LLVM_StackMaps:12; Header13; CHECK-NEXT: .byte 314; CHECK-NEXT: .byte 015; CHECK-NEXT: .short 016; Num Functions17; CHECK-NEXT: .long 1118; Num LargeConstants19; CHECK-NEXT: .long 320; Num Callsites21; CHECK-NEXT: .long 1122 23; Functions and stack size24; CHECK-NEXT: .quad _constantargs25; CHECK-NEXT: .quad 1626; CHECK-NEXT: .quad 127; CHECK-NEXT: .quad _osrinline28; CHECK-NEXT: .quad 3229; CHECK-NEXT: .quad 130; CHECK-NEXT: .quad _osrcold31; CHECK-NEXT: .quad 1632; CHECK-NEXT: .quad 133; CHECK-NEXT: .quad _propertyRead34; CHECK-NEXT: .quad 1635; CHECK-NEXT: .quad 136; CHECK-NEXT: .quad _propertyWrite37; CHECK-NEXT: .quad 1638; CHECK-NEXT: .quad 139; CHECK-NEXT: .quad _jsVoidCall40; CHECK-NEXT: .quad 1641; CHECK-NEXT: .quad 142; CHECK-NEXT: .quad _jsIntCall43; CHECK-NEXT: .quad 1644; CHECK-NEXT: .quad 145; CHECK-NEXT: .quad _spilledValue46; CHECK-NEXT: .quad 16047; CHECK-NEXT: .quad 148; CHECK-NEXT: .quad _liveConstant49; CHECK-NEXT: .quad 1650; CHECK-NEXT: .quad 151; CHECK-NEXT: .quad _clobberLR52; CHECK-NEXT: .quad 11253; CHECK-NEXT: .quad 154; CHECK-NEXT: .quad _floats55; CHECK-NEXT: .quad 3256; CHECK-NEXT: .quad 157 58; Num LargeConstants59; CHECK-NEXT: .quad 429496729560; CHECK-NEXT: .quad 429496729661; CHECK-NEXT: .quad 429496729762 63; Constant arguments64;65; CHECK-NEXT: .quad 166; CHECK-NEXT: .long L{{.*}}-_constantargs67; CHECK-NEXT: .short 068; CHECK-NEXT: .short 669; SmallConstant70; CHECK-NEXT: .byte 471; CHECK-NEXT: .byte 072; CHECK-NEXT: .short 873; CHECK-NEXT: .short 074; CHECK-NEXT: .short 075; CHECK-NEXT: .long 6553576; SmallConstant77; CHECK-NEXT: .byte 478; CHECK-NEXT: .byte 079; CHECK-NEXT: .short 880; CHECK-NEXT: .short 081; CHECK-NEXT: .short 082; CHECK-NEXT: .long 6553683; LargeConstant at index 084; CHECK-NEXT: .byte 585; CHECK-NEXT: .byte 086; CHECK-NEXT: .short 887; CHECK-NEXT: .short 088; CHECK-NEXT: .short 089; CHECK-NEXT: .long 090; LargeConstant at index 191; CHECK-NEXT: .byte 592; CHECK-NEXT: .byte 093; CHECK-NEXT: .short 894; CHECK-NEXT: .short 095; CHECK-NEXT: .short 096; CHECK-NEXT: .long 197; SmallConstant98; CHECK-NEXT: .byte 499; CHECK-NEXT: .byte 0100; CHECK-NEXT: .short 8101; CHECK-NEXT: .short 0102; CHECK-NEXT: .short 0103; CHECK-NEXT: .long 66104; LargeConstant at index 2105; CHECK-NEXT: .byte 5106; CHECK-NEXT: .byte 0107; CHECK-NEXT: .short 8108; CHECK-NEXT: .short 0109; CHECK-NEXT: .short 0110; CHECK-NEXT: .long 2111 112define void @constantargs() {113entry:114 %0 = inttoptr i64 244837814094590 to ptr115 tail call void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 1, i32 20, ptr %0, i32 0, i64 65535, i64 65536, i64 4294967295, i64 4294967296, i128 66, i128 4294967297)116 ret void117}118 119; Inline OSR Exit120;121; CHECK-LABEL: .long L{{.*}}-_osrinline122; CHECK-NEXT: .short 0123; CHECK-NEXT: .short 2124; CHECK-NEXT: .byte 1125; CHECK-NEXT: .byte 0126; CHECK-NEXT: .short 8127; CHECK-NEXT: .short {{[0-9]+}}128; CHECK-NEXT: .short 0129; CHECK-NEXT: .long 0130; CHECK-NEXT: .byte 1131; CHECK-NEXT: .byte 0132; CHECK-NEXT: .short 8133; CHECK-NEXT: .short {{[0-9]+}}134; CHECK-NEXT: .short 0135; CHECK-NEXT: .long 0136define void @osrinline(i64 %a, i64 %b) {137entry:138 ; Runtime void->void call.139 call void inttoptr (i64 244837814094590 to ptr)()140 ; Followed by inline OSR patchpoint with 12-byte shadow and 2 live vars.141 call void (i64, i32, ...) @llvm.experimental.stackmap(i64 3, i32 12, i64 %a, i64 %b)142 ret void143}144 145; Cold OSR Exit146;147; 2 live variables in register.148;149; CHECK-LABEL: .long L{{.*}}-_osrcold150; CHECK-NEXT: .short 0151; CHECK-NEXT: .short 2152; CHECK-NEXT: .byte 1153; CHECK-NEXT: .byte 0154; CHECK-NEXT: .short 8155; CHECK-NEXT: .short {{[0-9]+}}156; CHECK-NEXT: .short 0157; CHECK-NEXT: .long 0158; CHECK-NEXT: .byte 1159; CHECK-NEXT: .byte 0160; CHECK-NEXT: .short 8161; CHECK-NEXT: .short {{[0-9]+}}162; CHECK-NEXT: .short 0163; CHECK-NEXT: .long 0164define void @osrcold(i64 %a, i64 %b) {165entry:166 %test = icmp slt i64 %a, %b167 br i1 %test, label %ret, label %cold168cold:169 ; OSR patchpoint with 12-byte nop-slide and 2 live vars.170 %thunk = inttoptr i64 244837814094590 to ptr171 call void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 4, i32 20, ptr %thunk, i32 0, i64 %a, i64 %b)172 unreachable173ret:174 ret void175}176 177; Property Read178; CHECK-LABEL: .long L{{.*}}-_propertyRead179; CHECK-NEXT: .short 0180; CHECK-NEXT: .short 0181;182; FIXME: There are currently no stackmap entries. After moving to183; AnyRegCC, we will have entries for the object and return value.184define i64 @propertyRead(ptr %obj) {185entry:186 %resolveRead = inttoptr i64 244837814094590 to ptr187 %result = call i64 (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.i64(i64 5, i32 20, ptr %resolveRead, i32 1, ptr %obj)188 %add = add i64 %result, 3189 ret i64 %add190}191 192; Property Write193; CHECK-LABEL: .long L{{.*}}-_propertyWrite194; CHECK-NEXT: .short 0195; CHECK-NEXT: .short 2196; CHECK-NEXT: .byte 1197; CHECK-NEXT: .byte 0198; CHECK-NEXT: .short 8199; CHECK-NEXT: .short {{[0-9]+}}200; CHECK-NEXT: .short 0201; CHECK-NEXT: .long 0202; CHECK-NEXT: .byte 1203; CHECK-NEXT: .byte 0204; CHECK-NEXT: .short 8205; CHECK-NEXT: .short {{[0-9]+}}206; CHECK-NEXT: .short 0207; CHECK-NEXT: .long 0208define void @propertyWrite(i64 %dummy1, ptr %obj, i64 %dummy2, i64 %a) {209entry:210 %resolveWrite = inttoptr i64 244837814094590 to ptr211 call anyregcc void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 6, i32 20, ptr %resolveWrite, i32 2, ptr %obj, i64 %a)212 ret void213}214 215; Void JS Call216;217; 2 live variables in registers.218;219; CHECK-LABEL: .long L{{.*}}-_jsVoidCall220; CHECK-NEXT: .short 0221; CHECK-NEXT: .short 2222; CHECK-NEXT: .byte 1223; CHECK-NEXT: .byte 0224; CHECK-NEXT: .short 8225; CHECK-NEXT: .short {{[0-9]+}}226; CHECK-NEXT: .short 0227; CHECK-NEXT: .long 0228; CHECK-NEXT: .byte 1229; CHECK-NEXT: .byte 0230; CHECK-NEXT: .short 8231; CHECK-NEXT: .short {{[0-9]+}}232; CHECK-NEXT: .short 0233; CHECK-NEXT: .long 0234define void @jsVoidCall(i64 %dummy1, ptr %obj, i64 %arg, i64 %l1, i64 %l2) {235entry:236 %resolveCall = inttoptr i64 244837814094590 to ptr237 call void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 7, i32 20, ptr %resolveCall, i32 2, ptr %obj, i64 %arg, i64 %l1, i64 %l2)238 ret void239}240 241; i64 JS Call242;243; 2 live variables in registers.244;245; CHECK-LABEL: .long L{{.*}}-_jsIntCall246; CHECK-NEXT: .short 0247; CHECK-NEXT: .short 2248; CHECK-NEXT: .byte 1249; CHECK-NEXT: .byte 0250; CHECK-NEXT: .short 8251; CHECK-NEXT: .short {{[0-9]+}}252; CHECK-NEXT: .short 0253; CHECK-NEXT: .long 0254; CHECK-NEXT: .byte 1255; CHECK-NEXT: .byte 0256; CHECK-NEXT: .short 8257; CHECK-NEXT: .short {{[0-9]+}}258; CHECK-NEXT: .short 0259; CHECK-NEXT: .long 0260define i64 @jsIntCall(i64 %dummy1, ptr %obj, i64 %arg, i64 %l1, i64 %l2) {261entry:262 %resolveCall = inttoptr i64 244837814094590 to ptr263 %result = call i64 (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.i64(i64 8, i32 20, ptr %resolveCall, i32 2, ptr %obj, i64 %arg, i64 %l1, i64 %l2)264 %add = add i64 %result, 3265 ret i64 %add266}267 268; Spilled stack map values.269;270; Verify 28 stack map entries.271;272; CHECK-LABEL: .long L{{.*}}-_spilledValue273; CHECK-NEXT: .short 0274; CHECK-NEXT: .short 28275;276; Check that at least one is a spilled entry from RBP.277; Location: Indirect FP + ...278; CHECK: .byte 3279; CHECK-NEXT: .byte 0280; CHECK-NEXT: .short 281; CHECK-NEXT: .short 29282; CHECK-NEXT: .short 0283; CHECK-NEXT: .long284define 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) {285entry:286 call void (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.void(i64 11, i32 20, 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)287 ret void288}289 290; Map a constant value.291;292; CHECK-LABEL: .long L{{.*}}-_liveConstant293; CHECK-NEXT: .short 0294; 1 location295; CHECK-NEXT: .short 1296; Loc 0: SmallConstant297; CHECK-NEXT: .byte 4298; CHECK-NEXT: .byte 0299; CHECK-NEXT: .short 8300; CHECK-NEXT: .short 0301; CHECK-NEXT: .short 0302; CHECK-NEXT: .long 33303 304define void @liveConstant() {305 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 15, i32 8, i32 33)306 ret void307}308 309; Map a value when LR is the only free register.310;311; CHECK-LABEL: .long L{{.*}}-_clobberLR312; CHECK-NEXT: .short 0313; 1 location314; CHECK-NEXT: .short 1315; Loc 0: Indirect FP (r29) - offset316; CHECK-NEXT: .byte 3317; CHECK-NEXT: .byte 0318; CHECK-NEXT: .short 4319; CHECK-NEXT: .short 29320; CHECK-NEXT: .short 0321; CHECK-NEXT: .long -{{[0-9]+}}322define void @clobberLR(i32 %a) {323 tail call void asm sideeffect "nop", "~{x0},~{x1},~{x2},~{x3},~{x4},~{x5},~{x6},~{x7},~{x8},~{x9},~{x10},~{x11},~{x12},~{x13},~{x14},~{x15},~{x16},~{x17},~{x18},~{x19},~{x20},~{x21},~{x22},~{x23},~{x24},~{x25},~{x26},~{x27},~{x28},~{x29},~{x31}"() nounwind324 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 16, i32 8, i32 %a)325 ret void326}327 328; CHECK-LABEL: .long L{{.*}}-_floats329; CHECK-NEXT: .short 0330; Num Locations331; CHECK-NEXT: .short 6332; Loc 0: constant float stored to FP register333; CHECK-NEXT: .byte 1334; CHECK-NEXT: .byte 0335; CHECK-NEXT: .short 4336; CHECK-NEXT: .short {{.*}}337; CHECK-NEXT: .short 0338; CHECK-NEXT: .long 0339; Loc 0: constant double stored to FP register340; CHECK-NEXT: .byte 1341; CHECK-NEXT: .byte 0342; CHECK-NEXT: .short 8343; CHECK-NEXT: .short {{.*}}344; CHECK-NEXT: .short 0345; CHECK-NEXT: .long 0346; Loc 1: float value in FP register347; CHECK-NEXT: .byte 1348; CHECK-NEXT: .byte 0349; CHECK-NEXT: .short 4350; CHECK-NEXT: .short {{.*}}351; CHECK-NEXT: .short 0352; CHECK-NEXT: .long 0353; Loc 2: double value in FP register354; CHECK-NEXT: .byte 1355; CHECK-NEXT: .byte 0356; CHECK-NEXT: .short 8357; CHECK-NEXT: .short {{.*}}358; CHECK-NEXT: .short 0359; CHECK-NEXT: .long 0360; Loc 3: float on stack361; CHECK-NEXT: .byte 2362; CHECK-NEXT: .byte 0363; CHECK-NEXT: .short 8364; CHECK-NEXT: .short {{.*}}365; CHECK-NEXT: .short 0366; CHECK-NEXT: .long -{{.*}}367; Loc 4: double on stack368; CHECK-NEXT: .byte 2369; CHECK-NEXT: .byte 0370; CHECK-NEXT: .short 8371; CHECK-NEXT: .short {{.*}}372; CHECK-NEXT: .short 0373; CHECK-NEXT: .long -{{.*}}374define void @floats(float %f, double %g) {375 %ff = alloca float376 %gg = alloca double377 call void (i64, i32, ...) @llvm.experimental.stackmap(i64 888, i32 0, float 1.25,378 double 1.5, float %f, double %g, ptr %ff, ptr %gg)379 ret void380}381 382declare void @llvm.experimental.stackmap(i64, i32, ...)383declare void @llvm.experimental.patchpoint.void(i64, i32, ptr, i32, ...)384declare i64 @llvm.experimental.patchpoint.i64(i64, i32, ptr, i32, ...)385