diff options
Diffstat (limited to 'test/CodeGen/X86/regcall-no-plt.ll')
-rw-r--r-- | test/CodeGen/X86/regcall-no-plt.ll | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/test/CodeGen/X86/regcall-no-plt.ll b/test/CodeGen/X86/regcall-no-plt.ll new file mode 100644 index 000000000000..d525448b60ca --- /dev/null +++ b/test/CodeGen/X86/regcall-no-plt.ll @@ -0,0 +1,44 @@ +; RUN: llc -mtriple=x86_64-unknown-linux-gnu -relocation-model=pic < %s | FileCheck %s +; RUN: llc -mtriple=x86_64-freebsd -relocation-model=pic < %s | FileCheck %s + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; According to x86-64 psABI, xmm0-xmm7 can be used to pass function parameters. +;; However regcall calling convention uses also xmm8-xmm15 to pass function +;; parameters which violates x86-64 psABI. +;; Detail info about it can be found at: +;; https://sourceware.org/bugzilla/show_bug.cgi?id=21265 +;; +;; We encounter the violation symptom when using PIC with lazy binding +;; optimization. +;; In that case the PLT mechanism as described in x86_64 psABI will +;; not preserve xmm8-xmm15 registers and will lead to miscompilation. +;; +;; The agreed solution is to disable PLT for regcall calling convention for +;; SystemV using ELF format. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +declare void @lazy() +declare x86_regcallcc void @regcall_not_lazy() + +; CHECK-LABEL: foo: +; CHECK: callq lazy@PLT +; CHECK: callq *regcall_not_lazy@GOTPCREL(%rip) +define void @foo() nounwind { + call void @lazy() + call void @regcall_not_lazy() + ret void +} + +; CHECK-LABEL: tail_call_regcall: +; CHECK: jmpq *regcall_not_lazy@GOTPCREL(%rip) +define void @tail_call_regcall() nounwind { + tail call void @regcall_not_lazy() + ret void +} + +; CHECK-LABEL: tail_call_regular: +; CHECK: jmp lazy +define void @tail_call_regular() nounwind { + tail call void @lazy() + ret void +} |