summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp4
-rw-r--r--llvm/test/CodeGen/X86/cfguard-checks.ll33
-rw-r--r--llvm/test/CodeGen/X86/musttail-varargs.ll30
3 files changed, 47 insertions, 20 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index d4aaa7a9ee6..38f82c04296 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -3467,8 +3467,8 @@ SDValue X86TargetLowering::LowerFormalArguments(
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
index d2cd3c9f3ee..efd6e7bc11b 100644
--- a/llvm/test/CodeGen/X86/cfguard-checks.ll
+++ b/llvm/test/CodeGen/X86/cfguard-checks.ll
@@ -176,6 +176,39 @@ entry:
; 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
index 1144ce8eba7..5f5ce5f9af9 100644
--- a/llvm/test/CodeGen/X86/musttail-varargs.ll
+++ b/llvm/test/CodeGen/X86/musttail-varargs.ll
@@ -211,37 +211,31 @@ define void @f_thunk(i8* %this, ...) {
; 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 @@ define void @h_thunk(%struct.Foo* %this, ...) {
; 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
OpenPOWER on IntegriCloud