[LLVMdev] x86_fp80, f80, and -m96bit-long-double

Duncan Sands baldrick at free.fr
Tue Nov 2 01:13:03 PDT 2010


Hi Jonas,

>> I think the "fact" that x86 long double is 16 byte aligned on x86-64 is
>> hard-wired in.
>
> Note that it's not just about alignment, but mainly about the reserved storage size.

actually it is about the alignment, since the reserved storage size is (in LLVM)
the number of bytes needed to store the type (i.e. 10 bytes) rounded up by the
alignment.

>> I'm not sure how hard this would be to control via a
>> command line option (i.e. -m96bit-long-double).
>
> Is there no different way to go about this? Our compiler currently supports the x87 long double type as
> a) 10 bytes, for Turbo Pascal and Delphi-compatibility

I doubt 10 bytes is supportable in LLVM without some surgery.  Consider an
array of long double,
   long double A[2];
Then the following should be true in C (not sure if the C standard requires
this, but gcc and clang seem to work this way):
   sizeof(long double) == (char*)&A[1] - (char*)&A[0]
If sizeof(long double) is 10, then this means that A[1] will not be aligned
if A[0] is aligned.  This is why sizeof is always a multiple of the alignment.
So to get a sizeof of 10 bytes, you would either have to ditch this rule (ouch)
or drop the alignment of long double down to 2 (ouch).

> b) 12 bytes, for non-Darwin ABI/C x86 compatibility

This can be done easily by hand modifying LLVM, but I guess you don't want that.
This is the default on x86-32 linux targets.  On x86-64 targets it is 16 bytes,
and you want some method of overriding that.  Not sure what Chris's view on this
would be.

> c) 16 bytes, for Darwin x86 ABI/C and x86_64 ABI/C compatibility

This is what is hard-wired into LLVM right now.

> long doubles of type a) and c), or of type b) and c), can occur in the same compilation unit. A command line switch does not offer sufficient flexibility in this case.

Ah, I should have read this first!  In that case there is not really any choice.
In the LLVM IR, you should not work with arrays of long double, you should use
for example (in case a) arrays of [10 x i8].  You can still happily store a long
double into any position in the array (on all platforms storing a long double
only stores 10 bytes).  In short, on a platform where LLVM's getTypeAllocSize
(which is LLVM's notion of "sizeof") returns something different to what you
would like sizeof to be, you will have to allocate a different artificial type
to get the storage size you want.

Ciao,

Duncan.



More information about the llvm-dev mailing list