1; RUN: llc < %s -join-physregs -mtriple=x86_64-mingw32 | FileCheck %s -check-prefix=M64 2; RUN: llc < %s -join-physregs -mtriple=x86_64-win32 | FileCheck %s -check-prefix=W64 3; RUN: llc < %s -join-physregs -mtriple=x86_64-win32-macho | FileCheck %s -check-prefix=EFI 4; PR8777 5; PR8778 6 7; Passing the same value in two registers creates a false interference that 8; only -join-physregs resolves. It could also be handled by a parallel copy. 9 10define i64 @foo(i64 %n, i64 %x) nounwind { 11entry: 12 13 %buf0 = alloca i8, i64 4096, align 1 14 15; ___chkstk must adjust %rsp. 16; M64: movq %rsp, %rbp 17; M64: $4096, %rax 18; M64: callq ___chkstk 19; M64-NOT: %rsp 20 21; __chkstk does not adjust %rsp. 22; W64: movq %rsp, %rbp 23; W64: $4096, %rax 24; W64: callq __chkstk 25; W64: subq $4096, %rsp 26 27; Freestanding 28; EFI: movq %rsp, %rbp 29; EFI: $[[B0OFS:4096|4104]], %rsp 30; EFI-NOT: call 31 32 %buf1 = alloca i8, i64 %n, align 1 33 34; M64: leaq 15(%rcx), %rax 35; M64: andq $-16, %rax 36; M64: callq ___chkstk 37; M64-NOT: %rsp 38; M64: movq %rsp, %rax 39 40; W64: leaq 15(%rcx), %rax 41; W64: andq $-16, %rax 42; W64: callq __chkstk 43; W64: subq %rax, %rsp 44; W64: movq %rsp, %rax 45 46; EFI: leaq 15(%rcx), [[R1:%r.*]] 47; EFI: andq $-16, [[R1]] 48; EFI: movq %rsp, [[R64:%r.*]] 49; EFI: subq [[R1]], [[R64]] 50; EFI: movq [[R64]], %rsp 51 52 %r = call i64 @bar(i64 %n, i64 %x, i64 %n, i8* %buf0, i8* %buf1) nounwind 53 54; M64: subq $48, %rsp 55; M64: leaq -4096(%rbp), %r9 56; M64: movq %rax, 32(%rsp) 57; M64: callq bar 58 59; W64: subq $48, %rsp 60; W64: leaq -4096(%rbp), %r9 61; W64: movq %rax, 32(%rsp) 62; W64: callq bar 63 64; EFI: subq $48, %rsp 65; EFI: leaq -[[B0OFS]](%rbp), %r9 66; EFI: movq [[R64]], 32(%rsp) 67; EFI: callq _bar 68 69 ret i64 %r 70 71; M64: movq %rbp, %rsp 72 73; W64: movq %rbp, %rsp 74 75} 76 77declare i64 @bar(i64, i64, i64, i8* nocapture, i8* nocapture) nounwind 78