[PATCH] D115441: [X86][MS] Add 80bit long double support for Windows

Reid Kleckner via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 15 10:04:05 PST 2021


rnk added a comment.

Let me know if it would be more helpful to set up a call, that might help us reach agreement sooner. I've used discord for this previously if that works for you, my username there is the same (`@rnk#8591`).

In D115441#3194066 <https://reviews.llvm.org/D115441#3194066>, @pengfei wrote:

>> GCC doesn't align fp80 long double to 16 bytes on i686, so I see no reason for LLVM to do it. Is there some other compiler that you need ABI compatibility with?
>
> Yes. ICC aligns long double to 16 bytes on 32bit Windows. (I mentioned it in the summary :). In contrast with GCC, ICC is more compatible with MSVC. So I think it's reasonable to align with ICC ranther than GCC.

My comment here refers to the alignment of argument values, not user-declared variables. The frontend controls the alignment of user-declared variables by setting the alloca alignment. GCC and ICC appear to align long double arguments to 4 bytes: https://gcc.godbolt.org/z/PbobWdrPf

>> Also consider that in LLVM, the alignment of arguments passed in memory is not observable (unless byval or inalloca is used). If the user takes the address of an argument, they actually take the address of a local alloca, which is a copy of the argument. The frontend (clang) decides the alignment of the alloca.
>
> We cannot force user to always pass arguments by address. Once they are passed by value, (actually it's common in the code, we usually write like foo(double a) rather than foo(double *a) ), it turns to the scope of calling conversion. It's true all basic types except f80 is aligned to 4 when passed by value on 32 bits. But Windows 32 bits is not alone. Darwin 32 bits uses the same calling conversion for f80 too.

I don't intend to ask users to pass arguments by address. What I mean is, LLVM will copy an under-aligned long double argument passed in memory to properly aligned memory. Consider this example using double:
https://gcc.godbolt.org/z/v6oTfrTr5

  void escape(void*);
  void foo(int x, double d, int y) {
    escape(&x);
    escape(&d);
    escape(&y);
  }

-->

  "?foo@@YAXHNH at Z": # @"?foo@@YAXHNH at Z"
    push ebp
    mov ebp, esp
    # Align stack to 8 bytes
    and esp, -8
    sub esp, 8
    # Copy bytes of d to aligned memory
    movsd xmm0, qword ptr [ebp + 12] # xmm0 = mem[0],zero
    movsd qword ptr [esp], xmm0
    lea eax, [ebp + 8]
  ...
    # Take address of aligned alloca at ESP+0
    mov eax, esp
    push eax
    call "?escape@@YAXPAX at Z"



---

So, I'm still not convinced we have to change the LLVM data layout. Is there some other aspect of calling convention lowering that needs to know the alignment of long double?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115441/new/

https://reviews.llvm.org/D115441



More information about the cfe-commits mailing list