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 10 define i64 @foo(i64 %n, i64 %x) nounwind { 11 entry: 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 77 declare i64 @bar(i64, i64, i64, i8* nocapture, i8* nocapture) nounwind 78