This is an archive of the discontinued LLVM Phabricator instance.

Swift Calling Convention: add swiftcc
ClosedPublic

Authored by manmanren on Mar 3 2016, 12:10 PM.

Diff Detail

Repository
rL LLVM

Event Timeline

manmanren updated this revision to Diff 49764.Mar 3 2016, 12:10 PM
manmanren retitled this revision from to Swift Calling Convention: add swiftcc.
manmanren updated this object.
manmanren changed the visibility from "Public (No Login Required)" to "No One".
manmanren updated this object.Mar 3 2016, 1:48 PM
manmanren changed the visibility from "No One" to "Public (No Login Required)".
manmanren added reviewers: lhames, rengolin, rnk.
manmanren added subscribers: llvm-commits, rjmccall.
t.p.northover requested changes to this revision.Mar 9 2016, 12:23 PM
t.p.northover edited edge metadata.

Hi Manman,

I think the testing is too weak if we're going for ABI stability (particularly based on FastCC, which is explicitly called out in the LangRef as unstable and based on APCS). I'd actually strongly suggest Swift starts out with AAPCS_VFP on ARM.

Even with that, I'd suggest testing things like minimum stack slot size, alignment of objects on the stack, whether everything goes on the stack if something has. Probably on both iOS and WatchOS because I suspect those details differ based on type alignment.

For x86, you don't seem to test the new xmm registers at all.

Cheers.

Tim.

lib/Target/X86/X86CallingConv.td
196–199 ↗(On Diff #49764)

Why did you drop the CCIfType<[i1], CCPromoteToType<i8>>? Does Swift never return anything containing an i1 or something?

Probably worth commenting on the differences here too (adding R8, XMM2 and XMM3 it seems).

test/CodeGen/ARM/swift-ios.ll
8–13 ↗(On Diff #49764)

I don't think this is needed. Same with the other tests.

This revision now requires changes to proceed.Mar 9 2016, 12:23 PM
manmanren updated this revision to Diff 52589.Apr 4 2016, 11:40 AM
manmanren edited edge metadata.

Separate this patch into X86 and ARM. This is the updated version for X86.

Cheers,
Manman

Hi Manman,

I think the testing is too weak if we're going for ABI stability (particularly based on FastCC, which is explicitly called out in the LangRef as unstable and based on APCS). I'd actually strongly suggest Swift starts out with AAPCS_VFP on ARM.

I will update the ARM patch to base on AAPCS_VFP.

Even with that, I'd suggest testing things like minimum stack slot size, alignment of objects on the stack, whether everything goes on the stack if something has. Probably on both iOS and WatchOS because I suspect those details differ based on type alignment.

For x86, you don't seem to test the new xmm registers at all.

For x86, added tests for xmm and i1.

Cheers,
Manman

lib/Target/X86/X86CallingConv.td
196–199 ↗(On Diff #52589)

Hi Tim,

i1 type is promoted to i8 before reaching here. That is why we don't need to handle i1 here.
This is what other RetCCs do, such as RetCC_X86_32_Fast, but I am not against making it explicit here.

t.p.northover added inline comments.Apr 4 2016, 11:54 AM
lib/Target/X86/X86CallingConv.td
196–199 ↗(On Diff #52589)

Where does it get promoted? To me it looks like RetCC_X86_64 directly calls RetCC_X86_64_Swift, which doesn't handle it. It then gets forwarded to RetCC_X86Common which promotes to i8 and only uses AL, DL, CL.

I suspect you'll find that something like

define [4 x i1] @foo() {
    %res = insertvalue [4 x i1] undef, i1 true, 3
    ret [4 x i1] %res
}

does not do what you're expecting.

manmanren added inline comments.Apr 4 2016, 12:19 PM
lib/Target/X86/X86CallingConv.td
196–199 ↗(On Diff #52589)

Sorry that it took so long for me to get back on this!

It was promoted in TargetLoweringBase::computeRegisterProperties

// Inspect all of the ValueType's smaller than the largest integer
// register to see which ones need promotion.

TLI.getRegisterType(...) for i1 will return i8.

t.p.northover added inline comments.Apr 4 2016, 12:54 PM
lib/Target/X86/X86CallingConv.td
196–199 ↗(On Diff #52589)

Ah, I see. The i1 case is only needed for AVX-512 by the looks of it. Do you know if Swift has a position on that? I would expect the Linux crowd to want to try it out when the chips come along properly, even if Macs don't have them yet.

rjmccall added inline comments.Apr 4 2016, 1:26 PM
lib/Target/X86/X86CallingConv.td
196–199 ↗(On Diff #52589)

Steve Canon and I agreed that the swift CC should be stable independent of AVX settings, so you shouldn't ever see vectors larger than 16 bytes in backend lowering.

t.p.northover added inline comments.Apr 4 2016, 2:00 PM
lib/Target/X86/X86CallingConv.td
196–199 ↗(On Diff #52589)

Enabling AVX-512 makes i1 a legal type which affects the CC even for plain i1s (well, if they'd get passed in r8b). E.g. compiling my example with "-mcpu=skylake-avx512" changes the calling convention to indirect sret.

@Tim,

Do you have any other comment?

Thanks,
Manman

lib/Target/X86/X86CallingConv.td
196–199 ↗(On Diff #52589)

Yes, enabling AVX512 will make i1 a legal type. I wonder how other calling conventions (RetCC_X86_64_HiPE, RetCC_X86_64_WebKit_JS, RetCC_X86_32_Fast) do not need to handle i1.

I will add this line
CCIfType<[i1], CCPromoteToType<i8>>,

No other comments, the changes look pretty straightforward to me.

Tim.

lib/Target/X86/X86CallingConv.td
196–199 ↗(On Diff #52589)

At least WebKit and Fast have no concerns about ABI stability. Not sure about HiPE.

rjmccall added inline comments.Apr 4 2016, 3:03 PM
lib/Target/X86/X86CallingConv.td
196–199 ↗(On Diff #52589)

That is true for the C calling convention; it is not true for swiftcc. swiftcc will always treat a 512-bit vector as illegal and split it up. If we have an ABI break in the future that allows us to assume the existence of AVX, we can easily revisit that decision; but I specifically did not want to use the unstable C rule for swift.

t.p.northover added inline comments.Apr 4 2016, 3:08 PM
lib/Target/X86/X86CallingConv.td
196–199 ↗(On Diff #52589)

Which bit? I don't think anyone's mentioned passing actual vectors; this is an issue with scalar i1s being handled differently depending on whether AVX-512 is around or not.

manmanren added inline comments.Apr 4 2016, 3:11 PM
lib/Target/X86/X86CallingConv.td
196–199 ↗(On Diff #52589)

John,

I think we are probably talking about different things here. Tim was concerned that if we pass i1 as the 4th integer, it will not be passed in r8b. Because I didn't add "CCIfType<[i1], CCPromoteToType<i8>>," right before "CCIfType<[i8] , CCAssignToReg<[AL, DL, CL, R8B]>>", if we have an i1 reaching the code path here, it will fall to the common RetCC for X86.

I didn't include that line because other calling conventions did not and I thought we would not have i1 reaching here. It turns out that when we enable AVX512, we will actually have i1 reaching here.

Clang also may do something for i1 so it is possible that with clang, we will not have i1 reaching here, but it does not hurt to include it here :]

manmanren updated this revision to Diff 52630.Apr 4 2016, 3:12 PM
manmanren edited edge metadata.

Adding handling of i1.

t.p.northover accepted this revision.Apr 5 2016, 3:01 PM
t.p.northover edited edge metadata.

Looks good, thanks Manman!

This revision is now accepted and ready to land.Apr 5 2016, 3:01 PM
This revision was automatically updated to reflect the committed changes.