[llvm-dev] RFC: Implementing the Swift calling convention in LLVM and Clang

Renato Golin via llvm-dev llvm-dev at lists.llvm.org
Thu Mar 3 10:06:41 PST 2016


On 3 March 2016 at 17:36, John McCall <rjmccall at apple.com> wrote:
> I’m not sure of your point here.  We don’t use the Swift CC to call C functions.
> It does not matter, at all, whether the frontend lowering of an aggregate under
> the Swift CC resembles the frontend lowering of the same aggregate under AAPCS.

Right, ignore me, then.


> I’m not sure why you say that.  We already do have parameter ABI override
> attributes with target-specific behavior in LLVM IR: sret and inreg.

Their meaning is somewhat confused and hard-coded in the back-end. I
once wanted to use inreg for lowering register-based divmod in
SelectionDAG, but ended up implementing custom lowering in the ARM
back-end because inreg wasn't used correctly. It's possible that now
it's better, but you'll always be at the mercy of what the back-end
does with the attributes, especially in custom lowering.

Also, for different back-ends, "inreg" means different things. If the
PCS allows multiple argument/return registers, then sret inreg is
possible for a structure with up to X/Y words, where X and Y are
different for different targets and could very well be zero.

Example, in a machine with *two* PCS registers:

i64 @foo (i32)

returning in registers becomes: sret { i32, i32 } @foo (inreg i32)

then you add your error: sret { i32, i32, i8* } @foo (inreg i32, inreg i8*)

You can fit the two arguments in registers, but you can't fit the
result + error in your sret.

Targets will have to deal with that in the DAG, if you don't do that
in IR. The ARM target would put the error pointer in the stack, which
is not where you want it to go.

You'd probably need a way to mark portions of your sret as *must be
inreg* and others to be "nice to be inreg", so that you can spill the
result and not the error, if that's what you want.


> Having that sort of ability might make some special cases easier for C lowering,
> too, come to think of it.  Imagine an x86 ABI that — based on type information
> otherwise erased by the conversion to LLVM IR — sometimes returns a float in
> an SSE register and sometimes on the x86 stack.  It would be very awkward to
> express that today, but some sort of abi(“x87”) attribute would make it easy.

If this is kept in Swift PCS only, and if the compiler always agree on
which registers you're using, that's ok.

But if you call a C function, or a new version of LLVM decides to use
a different register, you'll have run-time problems.

That's why ARM has different standards for hard and soft float, which
cannot mix.

cheers,
--renato


More information about the llvm-dev mailing list