diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -3467,8 +3467,8 @@ FuncInfo->getForwardedMustTailRegParms(); CCInfo.analyzeMustTailForwardedRegisters(Forwards, RegParmTypes, CC_X86); - // Conservatively forward AL on x86_64, since it might be used for varargs. - if (Is64Bit && !CCInfo.isAllocated(X86::AL)) { + // Forward AL for SysV x86_64 targets, since it is used for varargs. + if (Is64Bit && !IsWin64 && !CCInfo.isAllocated(X86::AL)) { unsigned ALVReg = MF.addLiveIn(X86::AL, &X86::GR8RegClass); Forwards.push_back(ForwardedRegister(ALVReg, X86::AL, MVT::i8)); } diff --git a/llvm/test/CodeGen/X86/cfguard-checks.ll b/llvm/test/CodeGen/X86/cfguard-checks.ll --- a/llvm/test/CodeGen/X86/cfguard-checks.ll +++ b/llvm/test/CodeGen/X86/cfguard-checks.ll @@ -176,6 +176,39 @@ ; X64-NOT: callq } +%struct.Foo = type { i32 (%struct.Foo*)** } + +; Test that Control Flow Guard checks are correctly added for variadic musttail +; calls. These are used for MS C++ ABI virtual member pointer thunks. +; PR44049 +define i32 @vmptr_thunk(%struct.Foo* inreg %p) { +entry: + %vptr.addr = getelementptr inbounds %struct.Foo, %struct.Foo* %p, i32 0, i32 0 + %vptr = load i32 (%struct.Foo*)**, i32 (%struct.Foo*)*** %vptr.addr + %slot = getelementptr inbounds i32 (%struct.Foo*)*, i32 (%struct.Foo*)** %vptr, i32 1 + %vmethod = load i32 (%struct.Foo*)*, i32 (%struct.Foo*)** %slot + %rv = musttail call i32 %vmethod(%struct.Foo* inreg %p) + ret i32 %rv + + ; On i686, the call to __guard_check_icall_fptr should come immediately before the call to the target function. + ; X32-LABEL: _vmptr_thunk: + ; X32: movl %eax, %esi + ; X32: movl (%eax), %eax + ; X32: movl 4(%eax), %ecx + ; X32: calll *___guard_check_icall_fptr + ; X32: movl %esi, %eax + ; X32: jmpl *%ecx # TAILCALL + ; X32-NOT: calll + + ; Use NEXT here because we previously had an extra instruction in this sequence. + ; X64-LABEL: vmptr_thunk: + ; X64: movq (%rcx), %rax + ; X64-NEXT: movq 8(%rax), %rax + ; X64-NEXT: movq __guard_dispatch_icall_fptr(%rip), %rdx + ; X64-NEXT: addq $40, %rsp + ; X64-NEXT: rex64 jmpq *%rdx # TAILCALL + ; X64-NOT: callq +} ; Test that longjmp targets have public labels and are included in the .gljmp section. %struct._SETJMP_FLOAT128 = type { [2 x i64] } diff --git a/llvm/test/CodeGen/X86/musttail-varargs.ll b/llvm/test/CodeGen/X86/musttail-varargs.ll --- a/llvm/test/CodeGen/X86/musttail-varargs.ll +++ b/llvm/test/CodeGen/X86/musttail-varargs.ll @@ -211,37 +211,31 @@ ; WINDOWS-NEXT: .seh_pushreg %rsi ; WINDOWS-NEXT: pushq %rdi ; WINDOWS-NEXT: .seh_pushreg %rdi -; WINDOWS-NEXT: pushq %rbp -; WINDOWS-NEXT: .seh_pushreg %rbp ; WINDOWS-NEXT: pushq %rbx ; WINDOWS-NEXT: .seh_pushreg %rbx -; WINDOWS-NEXT: subq $64, %rsp -; WINDOWS-NEXT: .seh_stackalloc 64 +; WINDOWS-NEXT: subq $72, %rsp +; WINDOWS-NEXT: .seh_stackalloc 72 ; WINDOWS-NEXT: .seh_endprologue -; WINDOWS-NEXT: movl %eax, %r14d -; WINDOWS-NEXT: movq %r9, %rsi +; WINDOWS-NEXT: movq %r9, %r14 ; WINDOWS-NEXT: movq %r8, %rdi ; WINDOWS-NEXT: movq %rdx, %rbx -; WINDOWS-NEXT: movq %rcx, %rbp +; WINDOWS-NEXT: movq %rcx, %rsi ; WINDOWS-NEXT: movq %rdx, {{[0-9]+}}(%rsp) ; WINDOWS-NEXT: movq %r8, {{[0-9]+}}(%rsp) ; WINDOWS-NEXT: movq %r9, {{[0-9]+}}(%rsp) ; WINDOWS-NEXT: leaq {{[0-9]+}}(%rsp), %rax ; WINDOWS-NEXT: movq %rax, {{[0-9]+}}(%rsp) ; WINDOWS-NEXT: callq get_f -; WINDOWS-NEXT: movq %rax, %r10 -; WINDOWS-NEXT: movq %rbp, %rcx +; WINDOWS-NEXT: movq %rsi, %rcx ; WINDOWS-NEXT: movq %rbx, %rdx ; WINDOWS-NEXT: movq %rdi, %r8 -; WINDOWS-NEXT: movq %rsi, %r9 -; WINDOWS-NEXT: movl %r14d, %eax -; WINDOWS-NEXT: addq $64, %rsp +; WINDOWS-NEXT: movq %r14, %r9 +; WINDOWS-NEXT: addq $72, %rsp ; WINDOWS-NEXT: popq %rbx -; WINDOWS-NEXT: popq %rbp ; WINDOWS-NEXT: popq %rdi ; WINDOWS-NEXT: popq %rsi ; WINDOWS-NEXT: popq %r14 -; WINDOWS-NEXT: rex64 jmpq *%r10 # TAILCALL +; WINDOWS-NEXT: rex64 jmpq *%rax # TAILCALL ; WINDOWS-NEXT: .seh_handlerdata ; WINDOWS-NEXT: .text ; WINDOWS-NEXT: .seh_endproc @@ -397,14 +391,14 @@ ; WINDOWS-NEXT: cmpb $1, (%rcx) ; WINDOWS-NEXT: jne .LBB2_2 ; WINDOWS-NEXT: # %bb.1: # %then -; WINDOWS-NEXT: movq 8(%rcx), %r10 +; WINDOWS-NEXT: movq 8(%rcx), %rax ; WINDOWS-NEXT: addq $40, %rsp -; WINDOWS-NEXT: rex64 jmpq *%r10 # TAILCALL +; WINDOWS-NEXT: rex64 jmpq *%rax # TAILCALL ; WINDOWS-NEXT: .LBB2_2: # %else -; WINDOWS-NEXT: movq 16(%rcx), %r10 +; WINDOWS-NEXT: movq 16(%rcx), %rax ; WINDOWS-NEXT: movl $42, {{.*}}(%rip) ; WINDOWS-NEXT: addq $40, %rsp -; WINDOWS-NEXT: rex64 jmpq *%r10 # TAILCALL +; WINDOWS-NEXT: rex64 jmpq *%rax # TAILCALL ; WINDOWS-NEXT: .seh_handlerdata ; WINDOWS-NEXT: .text ; WINDOWS-NEXT: .seh_endproc