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

Reid Kleckner via cfe-dev cfe-dev at lists.llvm.org
Wed Mar 2 12:00:57 PST 2016

On Tue, Mar 1, 2016 at 5:14 PM, John McCall via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> There are four general points of deviation from the intermediary
> convention:
>   - We sometimes want to return more values in registers than the
> convention normally does, and we want to be able to use both integer and
> floating-point registers.  For example, we want to return a value of struct
> A, above, purely in registers.  For the most part, I don’t think this is a
> problem to layer on to an existing IR convention: C frontends will
> generally use explicit sret arguments when the convention requires them,
> and so the Swift lowering will produce result types that don’t have legal
> interpretations as direct results under the C convention.  But we can use a
> different IR convention if it’s necessary to disambiguate Swift’s desired
> treatment from the target's normal attempts to retroactively match the C
> convention.

You're suggesting that backends shouldn't try to turn returns of {i32,
float, i32} into sret automatically if the C ABI would require that struct
to be returned indirectly. I know there are many users of LLVM out there
that wish that LLVM would just follow the C ABI for them in "simple" cases
like this, even though in general it's a lost cause. I think if you hide
this new behavior under your own swiftcc then we can keep those people
happy, ish.

  - We sometimes have both direct results and indirect results.  It would
> be nice to take advantage of the sret convention even in the presence of
> direct results on targets that do use a different (profitable) ABI
> treatment for it.  I don’t know how well-supported this is in LLVM.

LLVM insists that sret functions be void because the C convention requires
the sret pointer to be returned in the normal return register. X86 Sys V
requires this, though LLVM does not leverage it, and was non-conforming for
most of its life. I don't see why Swift would need to use the 'sret'
attribute for indirect results, though, if it doesn't need to conform to
that part of the x86 convention. Am I missing something profitable about
reusing our sret support?

>   - We want a special “context” treatment for a certain argument.  A
> pointer-sized value is passed in an integer register; the same value should
> be present in that register after the call.  In some cases, the caller may
> pass a context argument to a function that doesn’t expect one, and this
> should not trigger undefined behavior.  Both of these rules suggest that
> the context argument be passed in a register which is normally callee-save.

As discussed later, these arguments would come last. I thought it was
already legal to call a C function with too many arguments without invoking
UB, so I think we have to keep this working in LLVM anyway.

>   - The “error” treatment requires some way to (1) pass and receive the
> value in the caller and (2) receive and change the value in the callee.
> The best way we could think of to represent this was to pretend that the
> argument is actually passed indirectly; the value is “passed” by storing to
> the pointer and “received” by loading from it.  To simplify backend
> lowering, we require the argument to be a special kind of swifterror alloca
> that can only be loaded, stored, and passed as a swifterror argument; in
> the callee, swifterror arguments have similar restrictions.  This ends up
> being fairly invasive in the backend, unfortunately.

This seems unfortunate. I guess you've already rejected returning an FCA. I
wonder if we should ever go back to the world of "only calls can produce
multiple values" as a special case, since that's what really happens at the
MI level. I wonder if operand bundles or tokens could help solve this


In general, yes, I'm in favor of upstreaming this Swift CC support. The
main awkwardness here to me is the error value which is in memory in the
mid-level, but in registers in the backend. I feel like
intrinsic/token/bundle/glue stuff might actually be better.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160302/b1ed20eb/attachment.html>

More information about the cfe-dev mailing list