[PATCH] D91020: [X86] Unbind the ebx with GOT address in regcall calling convention
LuoYuanke via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Nov 7 22:24:01 PST 2020
LuoYuanke added inline comments.
================
Comment at: llvm/lib/Target/X86/X86ISelLowering.cpp:4120
if (Subtarget.isPICStyleGOT()) {
// ELF / PIC requires GOT in the EBX register before function calls via PLT
+ // GOT pointer (except regcall).
----------------
To be conservative, do you need to check if the argument number exceed 4 (>=5)?
================
Comment at: llvm/lib/Target/X86/X86ISelLowering.cpp:4136
// Note: The actual moving to ECX is done further down.
GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee);
----------------
xiangzhangllvm wrote:
> LuoYuanke wrote:
> > Would you add a test case for tail call? Is there any conflict to ECX?
> I check here local before, For X86, tail call will not work with regcall, For X86_64 it will work, but X86_64 don't fix ebx with GOT point.
> please check the following case, it will not generate jump for 2nd command.
>
> ```
> 1 ; llc -mtriple=x86_64-unknown-linux-gnu -relocation-model=pic
> 2 ; llc -mtriple=i386-unknown-linux-gnu -relocation-model=pic <-tailcallopt>
> 3
> 4 declare x86_regcallcc void @regcall_not_lazy(i32 %a0, i32 %b0)
> 5
> 6 define void @tail_call_regcall() nounwind {
> 7 tail call x86_regcallcc void @regcall_not_lazy(i32 0, i32 1)
> 8 ret void
> 9 }
> ```
It seems compiler generate jmp instruction only when the argument number is less or equal to 2 and without pic relocation model.
```
; llc -mtriple=x86_64-unknown-linux-gnu
; llc -mtriple=i386-unknown-linux-gnu
@foo6 = external global void (i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5)*
define void @tail_call_regcall6(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, ...) nounwind {
%t0 = alloca i32, align 128
%t1 = load void (i32, i32, i32, i32, i32, i32)*, void (i32, i32, i32, i32, i32, i32)** @foo6, align 4
tail call x86_regcallcc void %t1(i32 0, i32 1, i32 2, i32 3, i32 4, i32 5) nounwind
ret void
}
@foo5 = external global void (i32 %0, i32 %1, i32 %2, i32 %3, i32 %4)*
define void @tail_call_regcall5(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) nounwind {
%t1 = load void (i32, i32, i32, i32, i32)*, void (i32, i32, i32, i32, i32)** @foo5, align 4
; tail call x86_regcallcc void %t1(i32 0, i32 1, i32 2, i32 3, i32 4) nounwind
tail call x86_regcallcc void %t1(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) nounwind
ret void
}
@foo4 = external global void (i32 %0, i32 %1, i32 %2, i32 %3)*
define void @tail_call_regcall4(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
%t1 = load void (i32, i32, i32, i32)*, void (i32, i32, i32, i32)** @foo4, align 4
; tail call x86_regcallcc void %t1(i32 0, i32 1, i32 2, i32 3, i32 4) nounwind
tail call x86_regcallcc void %t1(i32 %a, i32 %b, i32 %c, i32 %d) nounwind
ret void
}
@foo3 = external global void (i32 %0, i32 %1, i32 %2)*
define void @tail_call_regcall3(i32 %a, i32 %b) nounwind {
%t1 = load void (i32, i32, i32)*, void (i32, i32, i32)** @foo3, align 4
tail call x86_regcallcc void %t1(i32 0, i32 1, i32 2) nounwind
ret void
}
@foo2 = external global void (i32 %0, i32 %1)*
define void @tail_call_regcall2(i32 %a, i32 %b) nounwind {
%t1 = load void (i32, i32)*, void (i32, i32)** @foo2, align 4
tail call x86_regcallcc void %t1(i32 0, i32 1) nounwind
; tail call x86_regcallcc void %t1(i32 %a, i32 %b) nounwind
ret void
}
```
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D91020/new/
https://reviews.llvm.org/D91020
More information about the llvm-commits
mailing list