Page MenuHomePhabricator

[PowerPC] Add clang -msvr4-struct-return for 32-bit ELF

Authored by kernigh on Jan 23 2020, 1:17 PM.



This is a patch for

Beware: This diff passes its own tests, and writes asm that looks correct to me, but I have not yet tried running the code on PowerPC. I intend to backport the diff to llvm/clang 8.0.1 (the version in OpenBSD), and try it on an old and slow PowerPC Macintosh. I upload the diff now, because other people might want to see it.

This is only my 2nd patch on, so I might have filled some fields wrong. I don't have commit access to LLVM.

[PowerPC] Add clang -msvr4-struct-return for 32-bit ELF

Change the default ABI to be compatible with GCC. For 32-bit ELF targets other than Linux, Clang now returns small structs in registers r3/r4. This affects FreeBSD, NetBSD, OpenBSD. There is no change for 32-bit Linux, where Clang continues to return all structs in memory.

Add clang options -maix-struct-return (to return structs in memory) and -msvr4-struct-return (to return structs in registers) to be compatible with gcc. These options are only for PPC32; reject them on PPC64 and other targets. The options are like -fpcc-struct-return and -freg-struct-return for X86_32, and use similar code.

To actually return a struct in registers, coerce it to an integer of the same size. LLVM may optimize the code to remove unnecessary accesses to memory, and will return i32 in r3 or i64 in r3:r4.

Fixes PR#40736

Diff Detail

Event Timeline

kernigh created this revision.Jan 23 2020, 1:17 PM

Summary: My preliminary testing looks good.

FreeBSD does not have clang/test/ and clang/doc/ in its contrib/llvm-project/ so I applied just the other patches to my context and rebuilt my FreeBSD head -r356426 based context's clang/clang++ and such.
Using the updated compilers I did buildworld and buildkernel for 32-bit powerpc, installed them, and booted an old PowerMac 2-socket G4 with the result. After that I built the ports related to devel/freebsd-gcc9 at powerpc and lang/gcc9 and installed the packages the build produced. I then used such toolchains to build and run the original program that I found the ABI mismatch with, building without using -maix-struct-return but using FreeBSD's libc++ and such (like before).

The program ran fine.

The overall sequence I used involved buildworld buildkernel for powerpc64 and installing and booting such as well. That was in turn used to build some ports for 32-bit powerpc via devel/poudriere (so via chroot activity). All that worked fine.

It will be some time before all my usual ports have been built for 32-bit powerpc. But my preliminary testing is good news.

I built and installed ports, what built vs. did-not was the same as before applying the update, with the same failure details having nothing to do with this change. I then ran the FreeBSD kyua tests and the result match what I got prior to the update.

These tests are not about gcc/g++ ABI compatibility, but FreeBSD seems to work fine when built based on the change.

(FYI, given the ABI incompatibility, I did not try to self-host getting from one ABI to the other. I instead installed the updated FreeBSD as a separate drive on another system and then put that drive back in its normal system and booted from it.)

I'm not aware of anything around that makes for a good, fairly-general gcc/g++ ABI compatibility test.

brad added a comment.Apr 1 2020, 8:32 PM

Now that 10 is out, any chance of getting some movement on this to resolve this ABI issue with 32-bit PowerPC?

lkail added a reviewer: Restricted Project.Apr 1 2020, 8:49 PM
jhibbits accepted this revision.Apr 3 2020, 9:30 PM
jhibbits edited reviewers, added: jhibbits; removed: chmeee.
jhibbits added a subscriber: jhibbits.

Code looks fine, and others have tested it. Good to see a reversion of the ABI to expected for GCC compatibility on the BSDs.

This revision is now accepted and ready to land.Apr 3 2020, 9:30 PM
ZarkoCA added a subscriber: ZarkoCA.Apr 7 2020, 6:31 AM

@jhibbits is this patch going to be committed soon? I have a patch ( that I will need to rebase once this is in. Thanks.

@ZarkoCA I think someone else should also review this, so added @nemanjai as a potential reviewer. He might have more insight to the code in question. I'd like to see this go in soon, though, so that it gets into 11, and we can use it in FreeBSD.

nemanjai accepted this revision.Apr 20 2020, 9:56 AM

Aside from a couple of minor nits that shouldn't require another review, LGTM.


Can you specify that "small" means 8 bytes or smaller?


Please add text to the assert to help anyone who ends up tripping it. Perhaps:

assert(Triple.getArch() == llvm::Triple::ppc &&
       "Invalid triple for a 32-bit PowerPC target");
This revision was automatically updated to reflect the committed changes.