[LLVMbugs] [Bug 23897] New: x86_64 fp128 incorrect mangled name, calling convention
bugzilla-daemon at llvm.org
bugzilla-daemon at llvm.org
Fri Jun 19 11:57:14 PDT 2015
https://llvm.org/bugs/show_bug.cgi?id=23897
Bug ID: 23897
Summary: x86_64 fp128 incorrect mangled name, 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
clang -target x86_64-linux-android uses IEEEquad format (fp128) for long
double.
See latest change in http://reviews.llvm.org/D8357.
This is equivalent to gcc's __float128 type, but clang x86_64-linux-android's
long double type is still incompatible with gcc's __float128, or Android's gcc
long double for x86_64.
(1) Android x86_64 g++ uses mangled name 'g' for long double and __float128
types,
but clang target x86_64-linux-android uses 'e' for long double type.
(2) According to AMD64 ABI http://www.x86-64.org/documentation/abi.pdf
__float128 values should be passed and returned in SSE registers, xmm0 etc.,
but llvm uses %rsi and %rdi now.
llvm's X86CallingConv.td has handled f64 and f80, but not f128 yet.
The following test case runs on native x86_64 host
with g++ and long double implemented as fp80.
(a) llvm x86_64-linux-android's long double is fp128
but is not passed/returned as __float128.
(b) llvm x86_64-linux-gnu's long double is fp80
and is passed/returned as __float80.
$ cat t.cpp
typedef double D;
typedef long double LD;
extern "C" {
void printf(const char*, ...);
int memcmp(const void *s1, const void *s2, unsigned long);
void print_double_ptr(void*p);
void print_long_double_ptr(void*p);
void print_float80_ptr(void*p);
void print_float128_ptr(void*p);
void print_double_value(double v);
void print_long_double_value(long double v);
// pass my long double and let gcc x64 print it as __float80.
void print_float80_value(long double v);
// pass my long double and let gcc x64 print it as __float128.
void print_float128_value(long double v);
}
D myd = 1.0;
LD myld = 1.0L;
extern D gd; // gcc x64 double
extern LD gld; // gcc x64 long double
extern LD gf80; // gcc x64 __float80
extern LD gf128; // gcc x64 __float128
void mycompare(const char *msg, const void *s1, const void *s2, unsigned long
n) {
printf("%s: they are %s\n", msg, memcmp(s1, s2, n) ? "different" : "the
same");
}
extern "C" LD get_my_LD_as_LD() { return myld; }
extern "C" LD get_my_LD_as_F80() { return myld; }
extern "C" LD get_my_LD_as_F128() { return myld; }
void mytest() {
mycompare("my long double vs gcc long double", &myld, &gld, sizeof(myld));
mycompare("my long double vs gcc __float80", &myld, &gf80, sizeof(myld));
mycompare("my long double vs gcc __float128", &myld, &gf128, sizeof(myld));
print_double_ptr(&myd);
print_long_double_ptr(&myld);
print_float80_ptr(&myld);
print_float128_ptr(&myld);
printf("==== pass my long double to gcc x64 printer:\n");
print_double_value(myd);
print_long_double_value(myld);
print_float80_value(myld);
print_float128_value(myld);
}
$ cat dump.cpp
typedef double D;
typedef long double LD;
typedef __float80 F80;
typedef __float128 F128;
extern "C" {
void printf(const char*, ...);
void print_double_ptr(void*p)
{ printf(" as double ptr %f\n", (double)*(double*)p); }
void print_long_double_ptr(void*p)
{ printf(" as long double ptr %f\n", (double)*(long double*)p); }
void print_float80_ptr(void*p)
{ printf(" as __float80 ptr %f\n", (double)*(__float80*)p); }
void print_float128_ptr(void*p)
{ printf(" as __float128 ptr %f\n", (double)*(__float128*)p); }
void print_double_value(double v)
{ printf(" as double %f\n", (double)v); }
void print_long_double_value(long double v)
{ printf(" as long double %f\n", (double)v); }
void print_float80_value(F80 v)
{ printf(" as __float80 %f\n", (double)v); }
void print_float128_value(F128 v)
{ printf(" as __float128 %f\n", (double)v); }
}
D gd = 1.0;
LD gld = 1.0L;
F80 gf80 = 1.0L;
F128 gf128 = 1.0L;
extern "C" LD get_my_LD_as_LD();
extern "C" F80 get_my_LD_as_F80();
extern "C" F128 get_my_LD_as_F128();
void get_print_long_double() {
printf("==== get and print my long double:\n");
print_long_double_value(get_my_LD_as_LD());
print_float80_value(get_my_LD_as_F80());
print_float128_value(get_my_LD_as_F128());
}
int main() {
extern void mytest();
printf("gcc x64 sizeof(double)=%zu\nsizeof(long double)=%zu\n"
"sizeof(__float80)=%zu\nsizeof(__float128)=%zu\n",
sizeof(D), sizeof(LD), sizeof(F80), sizeof(F128));
mytest();
get_print_long_double();
return 0;
}
$ clang++ -target x86_64-linux-android -c -o ./t.android.o ./t.cpp
$ g++ -o dump.android.exe dump.cpp t.android.o
$ dump.android.exe
gcc x64 sizeof(double)=8
sizeof(long double)=16
sizeof(__float80)=16
sizeof(__float128)=16
my long double vs gcc long double: they are different
my long double vs gcc __float80: they are different
my long double vs gcc __float128: they are the same
as double ptr 1.000000
as long double ptr 0.000000
as __float80 ptr 0.000000
as __float128 ptr 1.000000
==== pass my long double to gcc x64 printer:
as double 1.000000
as long double -nan
as __float80 -nan
as __float128 0.000000
==== get and print my long double:
as long double 0.000000
as __float80 0.000000
as __float128 0.000000
$ clang++ -target x86_64-linux-gnu -c -o ./t.gnu.o ./t.cpp
$ g++ -o dump.gnu.exe dump.cpp t.gnu.o
$ dump.gnu.exe
gcc x64 sizeof(double)=8
sizeof(long double)=16
sizeof(__float80)=16
sizeof(__float128)=16
my long double vs gcc long double: they are the same
my long double vs gcc __float80: they are the same
my long double vs gcc __float128: they are different
as double ptr 1.000000
as long double ptr 1.000000
as __float80 ptr 1.000000
as __float128 ptr 0.000000
==== pass my long double to gcc x64 printer:
as double 1.000000
as long double 1.000000
as __float80 1.000000
as __float128 0.000000
==== get and print my long double:
as long double 1.000000
as __float80 1.000000
as __float128 0.000000
--
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/20150619/d3317032/attachment.html>
More information about the llvm-bugs
mailing list