<html>
<head>
<base href="https://llvm.org/bugs/" />
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW " title="NEW --- - x86_64 long double (f128) _Complex calling convention" href="https://urldefense.proofpoint.com/v2/url?u=https-3A__llvm.org_bugs_show-5Fbug.cgi-3Fid-3D24111&d=AwMBaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=pF93YEPyB-J_PERP4DUZOJDzFVX5ZQ57vQk33wu0vio&m=ckXB9O0B2HjbHUcsyxmTPQdSk92UlPEkjwAfFyucbZw&s=I0wAUzqDJyx9N3CyO4-wEpCDjUR7iEBFU1XLOhAYo9g&e=">24111</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>x86_64 long double (f128) _Complex calling convention
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Backend: X86
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>chh@google.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvmbugs@cs.uiuc.edu
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>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 <a class="bz_bug_link
bz_status_ASSIGNED " title="ASSIGNED --- - x86_64 fp128 incorrect mangled name, calling convention" href="show_bug.cgi?id=23897">https://llvm.org/bugs/show_bug.cgi?id=23897</a>,
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,@function
TestReturnValue: # @TestReturnValue
.cfi_startproc
# BB#0: # %entry
movq data@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,@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@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@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@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</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>