1; RUN: llc < %s -mtriple=x86_64-apple-darwin -disable-fp-elim | FileCheck %s 2; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7 -disable-fp-elim | FileCheck --check-prefix=SSE %s 3; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -disable-fp-elim | FileCheck --check-prefix=AVX %s 4 5 6; Stackmap Header: no constants - 6 callsites 7; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps 8; CHECK-NEXT: __LLVM_StackMaps: 9; Header 10; CHECK-NEXT: .byte 1 11; CHECK-NEXT: .byte 0 12; CHECK-NEXT: .short 0 13; Num Functions 14; CHECK-NEXT: .long 8 15; Num Constants 16; CHECK-NEXT: .long 0 17; Num Callsites 18; CHECK-NEXT: .long 8 19 20; Functions and stack size 21; CHECK-NEXT: .quad _test 22; CHECK-NEXT: .quad 8 23; CHECK-NEXT: .quad _property_access1 24; CHECK-NEXT: .quad 8 25; CHECK-NEXT: .quad _property_access2 26; CHECK-NEXT: .quad 24 27; CHECK-NEXT: .quad _property_access3 28; CHECK-NEXT: .quad 24 29; CHECK-NEXT: .quad _anyreg_test1 30; CHECK-NEXT: .quad 56 31; CHECK-NEXT: .quad _anyreg_test2 32; CHECK-NEXT: .quad 56 33; CHECK-NEXT: .quad _patchpoint_spilldef 34; CHECK-NEXT: .quad 56 35; CHECK-NEXT: .quad _patchpoint_spillargs 36; CHECK-NEXT: .quad 88 37 38; No constants 39 40; Callsites 41; test 42; CHECK-LABEL: .long L{{.*}}-_test 43; CHECK-NEXT: .short 0 44; 3 locations 45; CHECK-NEXT: .short 3 46; Loc 0: Register 47; CHECK-NEXT: .byte 1 48; CHECK-NEXT: .byte 4 49; CHECK-NEXT: .short {{[0-9]+}} 50; CHECK-NEXT: .long 0 51; Loc 1: Register 52; CHECK-NEXT: .byte 1 53; CHECK-NEXT: .byte 4 54; CHECK-NEXT: .short {{[0-9]+}} 55; CHECK-NEXT: .long 0 56; Loc 2: Constant 3 57; CHECK-NEXT: .byte 4 58; CHECK-NEXT: .byte 8 59; CHECK-NEXT: .short 0 60; CHECK-NEXT: .long 3 61define i64 @test() nounwind ssp uwtable { 62entry: 63 call anyregcc void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 0, i32 15, i8* null, i32 2, i32 1, i32 2, i64 3) 64 ret i64 0 65} 66 67; property access 1 - %obj is an anyreg call argument and should therefore be in a register 68; CHECK-LABEL: .long L{{.*}}-_property_access1 69; CHECK-NEXT: .short 0 70; 2 locations 71; CHECK-NEXT: .short 2 72; Loc 0: Register <-- this is the return register 73; CHECK-NEXT: .byte 1 74; CHECK-NEXT: .byte 8 75; CHECK-NEXT: .short {{[0-9]+}} 76; CHECK-NEXT: .long 0 77; Loc 1: Register 78; CHECK-NEXT: .byte 1 79; CHECK-NEXT: .byte 8 80; CHECK-NEXT: .short {{[0-9]+}} 81; CHECK-NEXT: .long 0 82define i64 @property_access1(i8* %obj) nounwind ssp uwtable { 83entry: 84 %f = inttoptr i64 12297829382473034410 to i8* 85 %ret = call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 1, i32 15, i8* %f, i32 1, i8* %obj) 86 ret i64 %ret 87} 88 89; property access 2 - %obj is an anyreg call argument and should therefore be in a register 90; CHECK-LABEL: .long L{{.*}}-_property_access2 91; CHECK-NEXT: .short 0 92; 2 locations 93; CHECK-NEXT: .short 2 94; Loc 0: Register <-- this is the return register 95; CHECK-NEXT: .byte 1 96; CHECK-NEXT: .byte 8 97; CHECK-NEXT: .short {{[0-9]+}} 98; CHECK-NEXT: .long 0 99; Loc 1: Register 100; CHECK-NEXT: .byte 1 101; CHECK-NEXT: .byte 8 102; CHECK-NEXT: .short {{[0-9]+}} 103; CHECK-NEXT: .long 0 104define i64 @property_access2() nounwind ssp uwtable { 105entry: 106 %obj = alloca i64, align 8 107 %f = inttoptr i64 12297829382473034410 to i8* 108 %ret = call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 2, i32 15, i8* %f, i32 1, i64* %obj) 109 ret i64 %ret 110} 111 112; property access 3 - %obj is a frame index 113; CHECK-LABEL: .long L{{.*}}-_property_access3 114; CHECK-NEXT: .short 0 115; 2 locations 116; CHECK-NEXT: .short 2 117; Loc 0: Register <-- this is the return register 118; CHECK-NEXT: .byte 1 119; CHECK-NEXT: .byte 8 120; CHECK-NEXT: .short {{[0-9]+}} 121; CHECK-NEXT: .long 0 122; Loc 1: Direct RBP - ofs 123; CHECK-NEXT: .byte 2 124; CHECK-NEXT: .byte 8 125; CHECK-NEXT: .short 6 126; CHECK-NEXT: .long 127define i64 @property_access3() nounwind ssp uwtable { 128entry: 129 %obj = alloca i64, align 8 130 %f = inttoptr i64 12297829382473034410 to i8* 131 %ret = call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 3, i32 15, i8* %f, i32 0, i64* %obj) 132 ret i64 %ret 133} 134 135; anyreg_test1 136; CHECK-LABEL: .long L{{.*}}-_anyreg_test1 137; CHECK-NEXT: .short 0 138; 14 locations 139; CHECK-NEXT: .short 14 140; Loc 0: Register <-- this is the return register 141; CHECK-NEXT: .byte 1 142; CHECK-NEXT: .byte 8 143; CHECK-NEXT: .short {{[0-9]+}} 144; CHECK-NEXT: .long 0 145; Loc 1: Register 146; CHECK-NEXT: .byte 1 147; CHECK-NEXT: .byte 8 148; CHECK-NEXT: .short {{[0-9]+}} 149; CHECK-NEXT: .long 0 150; Loc 2: Register 151; CHECK-NEXT: .byte 1 152; CHECK-NEXT: .byte 8 153; CHECK-NEXT: .short {{[0-9]+}} 154; CHECK-NEXT: .long 0 155; Loc 3: Register 156; CHECK-NEXT: .byte 1 157; CHECK-NEXT: .byte 8 158; CHECK-NEXT: .short {{[0-9]+}} 159; CHECK-NEXT: .long 0 160; Loc 4: Register 161; CHECK-NEXT: .byte 1 162; CHECK-NEXT: .byte 8 163; CHECK-NEXT: .short {{[0-9]+}} 164; CHECK-NEXT: .long 0 165; Loc 5: Register 166; CHECK-NEXT: .byte 1 167; CHECK-NEXT: .byte 8 168; CHECK-NEXT: .short {{[0-9]+}} 169; CHECK-NEXT: .long 0 170; Loc 6: Register 171; CHECK-NEXT: .byte 1 172; CHECK-NEXT: .byte 8 173; CHECK-NEXT: .short {{[0-9]+}} 174; CHECK-NEXT: .long 0 175; Loc 7: Register 176; CHECK-NEXT: .byte 1 177; CHECK-NEXT: .byte 8 178; CHECK-NEXT: .short {{[0-9]+}} 179; CHECK-NEXT: .long 0 180; Loc 8: Register 181; CHECK-NEXT: .byte 1 182; CHECK-NEXT: .byte 8 183; CHECK-NEXT: .short {{[0-9]+}} 184; CHECK-NEXT: .long 0 185; Loc 9: Register 186; CHECK-NEXT: .byte 1 187; CHECK-NEXT: .byte 8 188; CHECK-NEXT: .short {{[0-9]+}} 189; CHECK-NEXT: .long 0 190; Loc 10: Register 191; CHECK-NEXT: .byte 1 192; CHECK-NEXT: .byte 8 193; CHECK-NEXT: .short {{[0-9]+}} 194; CHECK-NEXT: .long 0 195; Loc 11: Register 196; CHECK-NEXT: .byte 1 197; CHECK-NEXT: .byte 8 198; CHECK-NEXT: .short {{[0-9]+}} 199; CHECK-NEXT: .long 0 200; Loc 12: Register 201; CHECK-NEXT: .byte 1 202; CHECK-NEXT: .byte 8 203; CHECK-NEXT: .short {{[0-9]+}} 204; CHECK-NEXT: .long 0 205; Loc 13: Register 206; CHECK-NEXT: .byte 1 207; CHECK-NEXT: .byte 8 208; CHECK-NEXT: .short {{[0-9]+}} 209; CHECK-NEXT: .long 0 210define i64 @anyreg_test1(i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13) nounwind ssp uwtable { 211entry: 212 %f = inttoptr i64 12297829382473034410 to i8* 213 %ret = call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 4, i32 15, i8* %f, i32 13, i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13) 214 ret i64 %ret 215} 216 217; anyreg_test2 218; CHECK-LABEL: .long L{{.*}}-_anyreg_test2 219; CHECK-NEXT: .short 0 220; 14 locations 221; CHECK-NEXT: .short 14 222; Loc 0: Register <-- this is the return register 223; CHECK-NEXT: .byte 1 224; CHECK-NEXT: .byte 8 225; CHECK-NEXT: .short {{[0-9]+}} 226; CHECK-NEXT: .long 0 227; Loc 1: Register 228; CHECK-NEXT: .byte 1 229; CHECK-NEXT: .byte 8 230; CHECK-NEXT: .short {{[0-9]+}} 231; CHECK-NEXT: .long 0 232; Loc 2: Register 233; CHECK-NEXT: .byte 1 234; CHECK-NEXT: .byte 8 235; CHECK-NEXT: .short {{[0-9]+}} 236; CHECK-NEXT: .long 0 237; Loc 3: Register 238; CHECK-NEXT: .byte 1 239; CHECK-NEXT: .byte 8 240; CHECK-NEXT: .short {{[0-9]+}} 241; CHECK-NEXT: .long 0 242; Loc 4: Register 243; CHECK-NEXT: .byte 1 244; CHECK-NEXT: .byte 8 245; CHECK-NEXT: .short {{[0-9]+}} 246; CHECK-NEXT: .long 0 247; Loc 5: Register 248; CHECK-NEXT: .byte 1 249; CHECK-NEXT: .byte 8 250; CHECK-NEXT: .short {{[0-9]+}} 251; CHECK-NEXT: .long 0 252; Loc 6: Register 253; CHECK-NEXT: .byte 1 254; CHECK-NEXT: .byte 8 255; CHECK-NEXT: .short {{[0-9]+}} 256; CHECK-NEXT: .long 0 257; Loc 7: Register 258; CHECK-NEXT: .byte 1 259; CHECK-NEXT: .byte 8 260; CHECK-NEXT: .short {{[0-9]+}} 261; CHECK-NEXT: .long 0 262; Loc 8: Register 263; CHECK-NEXT: .byte 1 264; CHECK-NEXT: .byte 8 265; CHECK-NEXT: .short {{[0-9]+}} 266; CHECK-NEXT: .long 0 267; Loc 9: Register 268; CHECK-NEXT: .byte 1 269; CHECK-NEXT: .byte 8 270; CHECK-NEXT: .short {{[0-9]+}} 271; CHECK-NEXT: .long 0 272; Loc 10: Register 273; CHECK-NEXT: .byte 1 274; CHECK-NEXT: .byte 8 275; CHECK-NEXT: .short {{[0-9]+}} 276; CHECK-NEXT: .long 0 277; Loc 11: Register 278; CHECK-NEXT: .byte 1 279; CHECK-NEXT: .byte 8 280; CHECK-NEXT: .short {{[0-9]+}} 281; CHECK-NEXT: .long 0 282; Loc 12: Register 283; CHECK-NEXT: .byte 1 284; CHECK-NEXT: .byte 8 285; CHECK-NEXT: .short {{[0-9]+}} 286; CHECK-NEXT: .long 0 287; Loc 13: Register 288; CHECK-NEXT: .byte 1 289; CHECK-NEXT: .byte 8 290; CHECK-NEXT: .short {{[0-9]+}} 291; CHECK-NEXT: .long 0 292define i64 @anyreg_test2(i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13) nounwind ssp uwtable { 293entry: 294 %f = inttoptr i64 12297829382473034410 to i8* 295 %ret = call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 5, i32 15, i8* %f, i32 8, i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13) 296 ret i64 %ret 297} 298 299; Test spilling the return value of an anyregcc call. 300; 301; <rdar://problem/15432754> [JS] Assertion: "Folded a def to a non-store!" 302; 303; CHECK-LABEL: .long L{{.*}}-_patchpoint_spilldef 304; CHECK-NEXT: .short 0 305; CHECK-NEXT: .short 3 306; Loc 0: Register (some register that will be spilled to the stack) 307; CHECK-NEXT: .byte 1 308; CHECK-NEXT: .byte 8 309; CHECK-NEXT: .short {{[0-9]+}} 310; CHECK-NEXT: .long 0 311; Loc 1: Register RDI 312; CHECK-NEXT: .byte 1 313; CHECK-NEXT: .byte 8 314; CHECK-NEXT: .short 5 315; CHECK-NEXT: .long 0 316; Loc 1: Register RSI 317; CHECK-NEXT: .byte 1 318; CHECK-NEXT: .byte 8 319; CHECK-NEXT: .short 4 320; CHECK-NEXT: .long 0 321define i64 @patchpoint_spilldef(i64 %p1, i64 %p2, i64 %p3, i64 %p4) { 322entry: 323 %result = tail call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 12, i32 15, i8* inttoptr (i64 0 to i8*), i32 2, i64 %p1, i64 %p2) 324 tail call void asm sideeffect "nop", "~{ax},~{bx},~{cx},~{dx},~{bp},~{si},~{di},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"() nounwind 325 ret i64 %result 326} 327 328; Test spilling the arguments of an anyregcc call. 329; 330; <rdar://problem/15487687> [JS] AnyRegCC argument ends up being spilled 331; 332; CHECK-LABEL: .long L{{.*}}-_patchpoint_spillargs 333; CHECK-NEXT: .short 0 334; CHECK-NEXT: .short 5 335; Loc 0: Return a register 336; CHECK-NEXT: .byte 1 337; CHECK-NEXT: .byte 8 338; CHECK-NEXT: .short {{[0-9]+}} 339; CHECK-NEXT: .long 0 340; Loc 1: Arg0 in a Register 341; CHECK-NEXT: .byte 1 342; CHECK-NEXT: .byte 8 343; CHECK-NEXT: .short {{[0-9]+}} 344; CHECK-NEXT: .long 0 345; Loc 2: Arg1 in a Register 346; CHECK-NEXT: .byte 1 347; CHECK-NEXT: .byte 8 348; CHECK-NEXT: .short {{[0-9]+}} 349; CHECK-NEXT: .long 0 350; Loc 3: Arg2 spilled to RBP + 351; CHECK-NEXT: .byte 3 352; CHECK-NEXT: .byte 8 353; CHECK-NEXT: .short 6 354; CHECK-NEXT: .long 355; Loc 4: Arg3 spilled to RBP + 356; CHECK-NEXT: .byte 3 357; CHECK-NEXT: .byte 8 358; CHECK-NEXT: .short 6 359; CHECK-NEXT: .long 360define i64 @patchpoint_spillargs(i64 %p1, i64 %p2, i64 %p3, i64 %p4) { 361entry: 362 tail call void asm sideeffect "nop", "~{ax},~{bx},~{cx},~{dx},~{bp},~{si},~{di},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"() nounwind 363 %result = tail call anyregcc i64 (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.i64(i64 13, i32 15, i8* inttoptr (i64 0 to i8*), i32 2, i64 %p1, i64 %p2, i64 %p3, i64 %p4) 364 ret i64 %result 365} 366 367; Make sure all regs are spilled 368define anyregcc void @anyregcc1() { 369entry: 370;SSE-LABEL: anyregcc1 371;SSE: pushq %rbp 372;SSE: pushq %rax 373;SSE: pushq %r15 374;SSE: pushq %r14 375;SSE: pushq %r13 376;SSE: pushq %r12 377;SSE: pushq %r11 378;SSE: pushq %r10 379;SSE: pushq %r9 380;SSE: pushq %r8 381;SSE: pushq %rdi 382;SSE: pushq %rsi 383;SSE: pushq %rdx 384;SSE: pushq %rcx 385;SSE: pushq %rbx 386;SSE: movaps %xmm15 387;SSE-NEXT: movaps %xmm14 388;SSE-NEXT: movaps %xmm13 389;SSE-NEXT: movaps %xmm12 390;SSE-NEXT: movaps %xmm11 391;SSE-NEXT: movaps %xmm10 392;SSE-NEXT: movaps %xmm9 393;SSE-NEXT: movaps %xmm8 394;SSE-NEXT: movaps %xmm7 395;SSE-NEXT: movaps %xmm6 396;SSE-NEXT: movaps %xmm5 397;SSE-NEXT: movaps %xmm4 398;SSE-NEXT: movaps %xmm3 399;SSE-NEXT: movaps %xmm2 400;SSE-NEXT: movaps %xmm1 401;SSE-NEXT: movaps %xmm0 402;AVX-LABEL:anyregcc1 403;AVX: pushq %rbp 404;AVX: pushq %rax 405;AVX: pushq %r15 406;AVX: pushq %r14 407;AVX: pushq %r13 408;AVX: pushq %r12 409;AVX: pushq %r11 410;AVX: pushq %r10 411;AVX: pushq %r9 412;AVX: pushq %r8 413;AVX: pushq %rdi 414;AVX: pushq %rsi 415;AVX: pushq %rdx 416;AVX: pushq %rcx 417;AVX: pushq %rbx 418;AVX: vmovaps %ymm15 419;AVX-NEXT: vmovaps %ymm14 420;AVX-NEXT: vmovaps %ymm13 421;AVX-NEXT: vmovaps %ymm12 422;AVX-NEXT: vmovaps %ymm11 423;AVX-NEXT: vmovaps %ymm10 424;AVX-NEXT: vmovaps %ymm9 425;AVX-NEXT: vmovaps %ymm8 426;AVX-NEXT: vmovaps %ymm7 427;AVX-NEXT: vmovaps %ymm6 428;AVX-NEXT: vmovaps %ymm5 429;AVX-NEXT: vmovaps %ymm4 430;AVX-NEXT: vmovaps %ymm3 431;AVX-NEXT: vmovaps %ymm2 432;AVX-NEXT: vmovaps %ymm1 433;AVX-NEXT: vmovaps %ymm0 434 call void asm sideeffect "", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{rbp},~{xmm0},~{xmm1},~{xmm2},~{xmm3},~{xmm4},~{xmm5},~{xmm6},~{xmm7},~{xmm8},~{xmm9},~{xmm10},~{xmm11},~{xmm12},~{xmm13},~{xmm14},~{xmm15}"() 435 ret void 436} 437 438; Make sure we don't spill any XMMs/YMMs 439declare anyregcc void @foo() 440define void @anyregcc2() { 441entry: 442;SSE-LABEL: anyregcc2 443;SSE-NOT: movaps %xmm 444;AVX-LABEL: anyregcc2 445;AVX-NOT: vmovups %ymm 446 %a0 = call <2 x double> asm sideeffect "", "={xmm0}"() nounwind 447 %a1 = call <2 x double> asm sideeffect "", "={xmm1}"() nounwind 448 %a2 = call <2 x double> asm sideeffect "", "={xmm2}"() nounwind 449 %a3 = call <2 x double> asm sideeffect "", "={xmm3}"() nounwind 450 %a4 = call <2 x double> asm sideeffect "", "={xmm4}"() nounwind 451 %a5 = call <2 x double> asm sideeffect "", "={xmm5}"() nounwind 452 %a6 = call <2 x double> asm sideeffect "", "={xmm6}"() nounwind 453 %a7 = call <2 x double> asm sideeffect "", "={xmm7}"() nounwind 454 %a8 = call <2 x double> asm sideeffect "", "={xmm8}"() nounwind 455 %a9 = call <2 x double> asm sideeffect "", "={xmm9}"() nounwind 456 %a10 = call <2 x double> asm sideeffect "", "={xmm10}"() nounwind 457 %a11 = call <2 x double> asm sideeffect "", "={xmm11}"() nounwind 458 %a12 = call <2 x double> asm sideeffect "", "={xmm12}"() nounwind 459 %a13 = call <2 x double> asm sideeffect "", "={xmm13}"() nounwind 460 %a14 = call <2 x double> asm sideeffect "", "={xmm14}"() nounwind 461 %a15 = call <2 x double> asm sideeffect "", "={xmm15}"() nounwind 462 call anyregcc void @foo() 463 call void asm sideeffect "", "{xmm0},{xmm1},{xmm2},{xmm3},{xmm4},{xmm5},{xmm6},{xmm7},{xmm8},{xmm9},{xmm10},{xmm11},{xmm12},{xmm13},{xmm14},{xmm15}"(<2 x double> %a0, <2 x double> %a1, <2 x double> %a2, <2 x double> %a3, <2 x double> %a4, <2 x double> %a5, <2 x double> %a6, <2 x double> %a7, <2 x double> %a8, <2 x double> %a9, <2 x double> %a10, <2 x double> %a11, <2 x double> %a12, <2 x double> %a13, <2 x double> %a14, <2 x double> %a15) 464 ret void 465} 466 467declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...) 468declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...) 469