From 1d4c94e1d4e803a0196cce93600496f85b0b5144 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Wed, 14 Feb 2018 00:22:20 +0000 Subject: Merging r325049: ------------------------------------------------------------------------ r325049 | rnk | 2018-02-13 12:47:49 -0800 (Tue, 13 Feb 2018) | 17 lines [X86] Use EDI for retpoline when no scratch regs are left Summary: Instead of solving the hard problem of how to pass the callee to the indirect jump thunk without a register, just use a CSR. At a call boundary, there's nothing stopping us from using a CSR to hold the callee as long as we save and restore it in the prologue. Also, add tests for this mregparm=3 case. I wrote execution tests for __llvm_retpoline_push, but they never got committed as lit tests, either because I never rewrote them or because they got lost in merge conflicts. Reviewers: chandlerc, dwmw2 Subscribers: javed.absar, kristof.beyls, hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D43214 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_60@325084 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/CodeGen/X86/retpoline-regparm.ll | 42 +++++++++++++++++++++++++++++++++++ test/CodeGen/X86/retpoline.ll | 14 +++++------- 2 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 test/CodeGen/X86/retpoline-regparm.ll (limited to 'test') diff --git a/test/CodeGen/X86/retpoline-regparm.ll b/test/CodeGen/X86/retpoline-regparm.ll new file mode 100644 index 00000000000..13b32740b28 --- /dev/null +++ b/test/CodeGen/X86/retpoline-regparm.ll @@ -0,0 +1,42 @@ +; RUN: llc -mtriple=i686-linux < %s | FileCheck --implicit-check-not="jmp.*\*" --implicit-check-not="call.*\*" %s + +; Test 32-bit retpoline when -mregparm=3 is used. This case is interesting +; because there are no available scratch registers. The Linux kernel builds +; with -mregparm=3, so we need to support it. TCO should fail because we need +; to restore EDI. + +define void @call_edi(void (i32, i32, i32)* %fp) #0 { +entry: + tail call void %fp(i32 inreg 0, i32 inreg 0, i32 inreg 0) + ret void +} + +; CHECK-LABEL: call_edi: +; EDI is used, so it must be saved. +; CHECK: pushl %edi +; CHECK-DAG: xorl %eax, %eax +; CHECK-DAG: xorl %edx, %edx +; CHECK-DAG: xorl %ecx, %ecx +; CHECK-DAG: movl {{.*}}, %edi +; CHECK: calll __llvm_retpoline_edi +; CHECK: popl %edi +; CHECK: retl + +define void @edi_external(void (i32, i32, i32)* %fp) #1 { +entry: + tail call void %fp(i32 inreg 0, i32 inreg 0, i32 inreg 0) + ret void +} + +; CHECK-LABEL: edi_external: +; CHECK: pushl %edi +; CHECK-DAG: xorl %eax, %eax +; CHECK-DAG: xorl %edx, %edx +; CHECK-DAG: xorl %ecx, %ecx +; CHECK-DAG: movl {{.*}}, %edi +; CHECK: calll __x86_indirect_thunk_edi +; CHECK: popl %edi +; CHECK: retl + +attributes #0 = { "target-features"="+retpoline" } +attributes #1 = { "target-features"="+retpoline-external-thunk" } diff --git a/test/CodeGen/X86/retpoline.ll b/test/CodeGen/X86/retpoline.ll index 57d3388b812..477609e2d10 100644 --- a/test/CodeGen/X86/retpoline.ll +++ b/test/CodeGen/X86/retpoline.ll @@ -340,10 +340,10 @@ latch: ; X86-NEXT: movl %edx, (%esp) ; X86-NEXT: retl ; -; X86-LABEL: .section .text.__llvm_retpoline_push,{{.*}},__llvm_retpoline_push,comdat -; X86-NEXT: .hidden __llvm_retpoline_push -; X86-NEXT: .weak __llvm_retpoline_push -; X86: __llvm_retpoline_push: +; X86-LABEL: .section .text.__llvm_retpoline_edi,{{.*}},__llvm_retpoline_edi,comdat +; X86-NEXT: .hidden __llvm_retpoline_edi +; X86-NEXT: .weak __llvm_retpoline_edi +; X86: __llvm_retpoline_edi: ; X86-NEXT: # {{.*}} # %entry ; X86-NEXT: calll [[CALL_TARGET:.*]] ; X86-NEXT: [[CAPTURE_SPEC:.*]]: # Block address taken @@ -355,11 +355,7 @@ latch: ; X86-NEXT: .p2align 4, 0x90 ; X86-NEXT: [[CALL_TARGET]]: # Block address taken ; X86-NEXT: # %entry -; X86-NEXT: addl $4, %esp -; X86-NEXT: pushl 4(%esp) -; X86-NEXT: pushl 4(%esp) -; X86-NEXT: popl 8(%esp) -; X86-NEXT: popl (%esp) +; X86-NEXT: movl %edi, (%esp) ; X86-NEXT: retl -- cgit v1.2.3