[PATCH] D109751: [Clang] Support conversion between PPC double-double and IEEE float128

Qiu Chaofan via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 7 21:12:46 PST 2021


qiucf added a comment.

In D109751#3168982 <https://reviews.llvm.org/D109751#3168982>, @hubert.reinterpretcast wrote:

> In D109751#3136543 <https://reviews.llvm.org/D109751#3136543>, @qiucf wrote:
>
>> Because the piece of code will be expanded to:
>>
>>   long double _Complex x;
>>   
>>   if ((__builtin_types_compatible_p(__typeof(creall(x)), _Float128)
>>            ? __isinff128(creall(x))
>>            : __builtin_isinf_sign(creall(x))) ||
>>       (__builtin_types_compatible_p(__typeof(cimagl(x)), _Float128)
>>            ? __isinff128(cimagl(x))
>>            : __builtin_isinf_sign(cimagl(x))))
>>     return inf;
>>
>> which requires 'long double' (the same semantics to `__ibm128` by default) and '_Float128' are compatible.
>
> Noting that the way the types are implemented in Clang, the conversion isn't the first problem with the above code. The types with the same representation are not considered "compatible" by Clang:
>
>   extern char x[__builtin_types_compatible_p(long double, __ibm128) ? 1 : -1]; // errors
>   extern char x[__builtin_types_compatible_p(long double, __ieee128) ? 1 : -1]; // errors too
>
> Compiler Explorer link: https://godbolt.org/z/fP3MfdexM

Thanks for the reminder. Here GCC and Clang diverges in the handling of `__ibm128`/`__float128` and `long double`. Not sure whether GCC will 'fix' the behavior, but here (and in most of the use case in glibc headers) it's `__builtin_types_compatible_p(..., _Float128)` where GCC/Clang behaves the same.



================
Comment at: clang/test/Sema/float128-ld-incompatibility.cpp:13
+long double ld{qf()}; // expected-error {{non-constant-expression cannot be narrowed from type '__float128' to 'long double' in initializer list}} expected-note {{insert an explicit cast to silence this issue}}
+__float128 q{ldf()}; // expected-no-error
 
----------------
hubert.reinterpretcast wrote:
> hubert.reinterpretcast wrote:
> > hubert.reinterpretcast wrote:
> > > Should also test `__ibm128` cases.
> > The C++ committee has advised that this implicit conversion should be considered ill-formed (see other comment).
> > 
> > Note that the //allowed// implicit conversion from `__ibm128` to `long double` (and vice versa) is still a conversion, which means that overload resolution is still a problem:
> > ```
> > void f(__ibm128);
> > void f(int);
> > void g(long double d) { return f(d); } // okay with GCC but not Clang; https://godbolt.org/z/fonsEbbY1
> > ```
> Even if the implicit conversion is to be allowed, there is not much reason why this is not considered narrowing (given the revised definition of narrowing conversions).
> 
> GCC's behaviour around the narrowing check has limited value as a reference point: Which of `__float128` or `__ibm128` is considered by GCC on Power to be the "wider type" depends on the `-mabi` option. That is, the behaviour is not consistent with there being a principled decision made by the GCC developers as to which representation format is "wider".
Thanks for the information. The behavior of GCC looks somewhat reasonable but I notice the naming convention of support functions is interesting: `__ibm128` to `__float128` is 'extend', `__float128` to `__ibm128` 'truncate'.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D109751



More information about the cfe-commits mailing list