Context can be found here:
RFC: Implementing the Swift calling convention in LLVM and Clang
https://groups.google.com/forum/#!topic/llvm-dev/epDd2w93kZ0
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
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. |
Separate this patch into X86 and ARM. This is the updated version for X86.
Cheers,
Manman
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. |
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. |
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. |
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. |
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. |
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. |
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 |
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. |
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. |
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. |
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 :] |