[PATCH, PowerPC] ABI fixes / improvements for powerpc64-linux

Ulrich Weigand Ulrich.Weigand at de.ibm.com
Tue Jul 8 10:11:16 PDT 2014


I've been working to verify ABI compatibility between GCC and LLVM on
powerpc64-linux using the GCC ABI compatibility test suite.  While for the
most part, the compilers are of course compatible in the "usual" scenarios,
this testing uncovered a number of bugs in corner-case situations.  [ Some
of these are actually GCC bugs which I'll be addressing on that side.  ]

In LLVM, the main issues I found are fixed by the patches attached here.
There are three issues (which are somewhat independent, but the patches
build on top of each other so I'll send them all in one mail):

- "synthetic" (non-Altivec) vector types

LLVM currently does not correctly implement the ABI for passing non-Altivec
vector types (defined via attribute((vector_size))).  While there is no
"official" ABI for these in any case, it still would make sense to
implement the ad-hoc ABI as implemented by GCC for those types.  This is
done by the following patch:
(See attached file: diff-clang-synthvector)

- Alignment of arguments in the parameter save area

Certain arguments are supposed to be aligned to a 16-byte boundary in the
argument save area.  This affects vector types as well as aggregates that
have a 16-byte (or higher) alignment requirement.  LLVM currently
implements this alignment for vector types, but not for aggregates, and it
does not respect the alignment at all (even for vector types) when
accessing a variable argument list via va_arg.

Aggregates are passed using the "byval" mechanism, so in theory either
Clang or LLVM could compute the correct alignment required for an aggregate
parameter.  However, it seems preferable to do this in Clang, since it has
the more complete type information, and Clang needs the information anyway
in order to expand va_arg correctly.  So this is what the following patch
does.  As a result, every byval parameter will now carry an explicit
"align" attribute in the IR created by Clang (which I understand is
recommended anyway?).

(See attached file: diff-clang-structalign)

- Avoiding "byval" for aggregates passed in registers

This is not actually a bug fix, but more of a code-gen enhancement.
(However, it will become a required feature for the ELFv2 little-endian
ABI, which I hope to post patches for shortly.)

Aggregates are currently always passed using the "byval" method.  However,
the first 64 bytes will end up in registers anyway, so it would improve
code generation if the IR made use of registers explicit (instead of using
byval).  The following patch implements this.  The main issue here is that
we need to track how many registers will end up being used by the previous
arguments.  However, due to the linear layout of the parameter area in the
ppc64 ABI, this is reasonably straight-forward (and there is precedent of
many other architectures likewise tracking register usage in Clang).

One extra trick is that aggregates that need 16-byte alignment now have to
get an explicit padding type to skip a register if needed.  For this to
work we need to both track registers used by previous arguments, and need
to compute alignment in Clang as introduced in the prior patch (so that's
another reason to do it in the front-end).

(See attached file: diff-clang-structpass)

Mit freundlichen Gruessen / Best Regards

Ulrich Weigand

  Dr. Ulrich Weigand | Phone: +49-7031/16-3727
  STSM, GNU/Linux compilers and toolchain
  IBM Deutschland Research & Development GmbH
  Vorsitzende des Aufsichtsrats: Martina Koederitz | Geschäftsführung: Dirk
  Sitz der Gesellschaft: Böblingen | Registergericht: Amtsgericht
Stuttgart, HRB 243294
-------------- next part --------------
A non-text attachment was scrubbed...
Name: diff-clang-synthvector
Type: application/octet-stream
Size: 4971 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140708/88f6c1ae/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: diff-clang-structalign
Type: application/octet-stream
Size: 6911 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140708/88f6c1ae/attachment-0001.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: diff-clang-structpass
Type: application/octet-stream
Size: 8232 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140708/88f6c1ae/attachment-0002.obj>

More information about the cfe-commits mailing list