[LLVMbugs] [Bug 24111] New: x86_64 long double (f128) _Complex calling convention

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Mon Jul 13 14:59:15 PDT 2015


https://llvm.org/bugs/show_bug.cgi?id=24111

            Bug ID: 24111
           Summary: x86_64 long double (f128) _Complex calling convention
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Backend: X86
          Assignee: unassignedbugs at nondot.org
          Reporter: chh at google.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

The following test program shows incompatible calling convention
between llvm's and gcc's 128-bit long double _Complex values.
This breaks Android libm long double _Complex functions when
compiled with clang/llvm.

(1) Both gcc and clang pass 128-bit long double _Complex values
    on stack. Gcc uses movdqa to copy 16-bytes of values through
    %xmm0, and clang/llvm uses movq to copy 8-bytes at a time.
    This should be still compatible, although llvm's code is less efficient.

(2) Gcc returns 128-bit long double _Complex values
    as a structure of two f128 values, copied the values
    16-bytes at a time to the location given by the caller.
    Clang/llvm returns the value as a pair of x86 fp80 values
    in ST(0) and ST(1) and convert from f128 to f80.
    This is incompatible with gcc.

Although AMD64 abi said that long double complex should be in
COMPLEX_87 registers, I think clang should treat long double complex
as long double __float128 and use f128 values like gcc does.

In https://llvm.org/bugs/show_bug.cgi?id=23897,
we found incompatibility between gcc's and clang's __float128.
Since AMD64 abi has special rule for __float128, to be passed in SSE registers
instead of x86 fp80 register stack, it would be more consistent to treat
long double (f128) _Complex values as a pair of __float128 instead of fp80.


Test input:

$ cat complex.c

long double _Complex data;
long double _Complex TestReturnValue() { return data; }
void TestParameter(long double _Complex c) { data = c; }


With current clang/llvm compiler:


.../bin/clang -target x86_64-linux-android -S -o complex.clang.s -O complex.c


cat complex.clang.s
        .text
        .file   "complex.c"
        .globl  TestReturnValue
        .align  16, 0x90
        .type   TestReturnValue, at function
TestReturnValue:                        # @TestReturnValue
        .cfi_startproc
# BB#0:                                 # %entry
        movq    data at GOTPCREL(%rip), %rax
        movq    (%rax), %rcx
        movq    8(%rax), %rdx
        movq    24(%rax), %rsi
        movq    16(%rax), %rax
        movq    %rcx, -24(%rsp)
        movw    %dx, -16(%rsp)
        fldt    -24(%rsp)
        movq    %rax, -40(%rsp)
        movw    %si, -32(%rsp)
        fldt    -40(%rsp)
        fxch    %st(1)
        retq
.Lfunc_end0:
        .size   TestReturnValue, .Lfunc_end0-TestReturnValue
        .cfi_endproc

        .globl  TestParameter
        .align  16, 0x90
        .type   TestParameter, at function
TestParameter:                          # @TestParameter
        .cfi_startproc
# BB#0:                                 # %entry
        movq    8(%rsp), %rax
        movq    16(%rsp), %rcx
        movq    24(%rsp), %rdx
        movq    32(%rsp), %rsi
        movq    data at GOTPCREL(%rip), %rdi
        movq    %rcx, 8(%rdi)
        movq    %rax, (%rdi)
        movq    %rsi, 24(%rdi)
        movq    %rdx, 16(%rdi)
        retq
.Lfunc_end1:
        .size   TestParameter, .Lfunc_end1-TestParameter
        .cfi_endproc



With Android prebuilt gcc compiler:

..../prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin/x86_64-linux-android-gcc
-S -O -o complex.gcc.s complex.c

cat complex.gcc.s

        .file   "complex.c"
        .text
        .globl  TestReturnValue
        .type   TestReturnValue, @function
TestReturnValue:
.LFB0:
        .cfi_startproc
        movq    %rdi, %rax
        movq    data at GOTPCREL(%rip), %rdx
        movdqa  (%rdx), %xmm0
        movdqa  %xmm0, (%rdi)
        movdqa  16(%rdx), %xmm0
        movdqa  %xmm0, 16(%rdi)
        ret
        .cfi_endproc
.LFE0:
        .size   TestReturnValue, .-TestReturnValue
        .globl  TestParameter
        .type   TestParameter, @function
TestParameter:
.LFB1:
        .cfi_startproc
        movq    data at GOTPCREL(%rip), %rax
        movdqa  8(%rsp), %xmm0
        movdqa  %xmm0, (%rax)
        movdqa  24(%rsp), %xmm0
        movdqa  %xmm0, 16(%rax)
        ret
        .cfi_endproc
.LFE1:
        .size   TestParameter, .-TestParameter

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20150713/027e5bd5/attachment.html>


More information about the llvm-bugs mailing list