[LLVMdev] How to represent __attribute__((fastcall)) functions in the IL

Chandler Carruth chandlerc at google.com
Fri Oct 19 08:40:27 PDT 2012

Personally, I'd love to see a setup where instead of LLVM implementing each
calling convention and ABI hack, we provide a means of actually describing
this. Specifically, I'd love to see a design for how to specify in the IR
which register(s) (if any register(s)) a particular value should be placed

Don't get me wrong, I don't have any good ideas about how to do this, I'm
just hoping someone does. End result might allow something like:

declare void @foo(double inreg <eax,edx> %x)

On Fri, Oct 19, 2012 at 8:17 AM, Rafael EspĂ­ndola <
rafael.espindola at gmail.com> wrote:

> Functions with __attribute__((fastcall)) pop their arguments and take
> up to two arguments in ecx and edx. Currently we represent them by
> just setting the x86_fastcallcc calling convention. The problem is
> that the ABI has some strange conventions on when a register is used
> or not. For example:
> void __attribute__((fastcall)) foo1(int y);
> will take 'y' in ecx, but
> struct S1 {
>   int x;
> };
> void __attribute__((fastcall)) foo2(struct S1 y);
> will use the stack. Even more surprising is that
> void __attribute__((fastcall)) foo8(struct S1 a, int b);
> will take 'a' in the stack but 'b' in *edx*. That is, the first
> argument consumed ecx but didn't use it. The implement this the IL
> needs to be able to represent that
> * an argument will go on registers
> * a register was consumed but unused
> A way to do this is to make clang produce byval for anything that goes
> on the stack, but that produces worse code as the caller now has to
> use an alloca instead of a simple value.
> Another option (which I implemented in a patch just sent to
> llvm-commits) is use the inreg attribute which we already use for the
> regparm C attribute. The above requirements are handled by putting
> inreg in the arguments that should go in register and creating a inreg
> padding argument when a register should be consumed but not used.
> The above examples would be irgened to:
> declare x86_fastcallcc void @foo1(i32 inreg
> declare x86_fastcallcc void @foo2(i32 inreg  /*dummy*/ , i32)
> declare x86_fastcallcc void @foo8(i32 inreg /*dummy*/, i32, i32 inreg)
> As Eli pointed out on llvm-commits, this would change the meaning of
> existing  x86_fastcallcc IL files, but given that they are only
> produced for fastcall C functions and those are fairly broken without
> this fix, I assume that is OK.
> Cheers,
> Rafael
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20121019/c587325e/attachment.html>

More information about the llvm-dev mailing list