-
-
Notifications
You must be signed in to change notification settings - Fork 265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ppc64(le): Add an option to use IEEE long double ABI on Linux #4833
base: master
Are you sure you want to change the base?
Conversation
... the system is using the new ABI that supports IEEE 754R long double instead of the legacy IBM double double format
... and then add a long double rewrite to convert it to ppc_f128 when lowering
... if -mabi=ieeelongdouble is specified on ppc64
... if IEEE long double ABI is selected
... to avoid a LLVM bug on multiple platforms
During the porting process, I discovered what seems to be an LLVM bug when targeting ppc64 using the IEEE long double ABI. Consider the following D code: extern (C++) real test1(real arg0)
{
if (!(arg0 == 0.0))
{
return 0.0;
}
else
{
return 0.0;
}
} LDC will generate the following LLVM IR (reduced, no optimization): target datalayout = "e-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512"
target triple = "powerpc64le-unknown-linux-gnu"
define fp128 @_Z5test1u9__ieee128(fp128 %0) {
%2 = fcmp ogt fp128 %0, 0xL00000000000000000000000000000000
%3 = icmp i1 %2, false
br i1 %3, label %5, label %4
4: ; preds = %1
ret fp128 0xL00000000000000000000000000000000
5: ; preds = %1
ret fp128 0xL00000000000000000000000000000000
} ... which will lead to what seems to be an infinite I have added a workaround solution in this pull request to replace |
Please also report the bug in LLVM's bug tracker. Nice that you are working on this btw ! |
driver/targetmachine.cpp
Outdated
@@ -108,6 +108,8 @@ const char *getABI(const llvm::Triple &triple, const llvm::SmallVectorImpl<llvm: | |||
return "elfv1"; | |||
if (ABIName.startswith("elfv2")) | |||
return "elfv2"; | |||
if (ABIName.startswith("ieeelongdouble")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense for a user to want to use ieeelongdouble
together with elfv1
or 2
? (seems logical, but I have no knowledge here)
If so, then this has to be rewritten to accept multiple options in mabi
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like both Clang and GCC do support accepting multiple -mabi=
values (only on ppc64 + big-endian systems, as ppc64le
only supports elfv2
).
However, GCC upstream wiki does mention ieeelongdouble
+ ppc64
+ elfv1
is an unsupported configuration: https://gcc.gnu.org/wiki/Ieee128PowerPC#A7.0_Transition_to_IEEE_128-bit_floating_point_as_the_default_for_long_double
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed now, you can use -mabi=elfv1 -mabi=ieeelongdouble
to enable IEEE long double on ppc64 (big-endian) systems. I have also added a logic where LDC will warn if this unsupported configuration is encountered.
driver/main.cpp
Outdated
@@ -683,6 +683,10 @@ void registerPredefinedTargetVersions() { | |||
if (triple.getOS() == llvm::Triple::Linux) { | |||
VersionCondition::addPredefinedGlobalIdent( | |||
triple.getArch() == llvm::Triple::ppc64 ? "ELFv1" : "ELFv2"); | |||
if (opts::mABI == "ieeelongdouble" && triple.isOSGlibc()) { | |||
// Only GLibc needs this for IEEELongDouble | |||
VersionCondition::addPredefinedGlobalIdent("D_PPCUseIEEE128"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add D_PPCUseIEEE128
as reserved version identifier upstream (dmd). Helps compatibility with GDC too.
Edit: example PR: dlang/dmd#16773
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! However, I am not entirely sure if identifiers starting with D_
are already classified as somewhat reserved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All identifiers starting with D_
are already reserved for the compiler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's good for documentation, and then you can sync/check with gdc too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think maybe we should also forward the phobos
changes to the D Language upstream? That way, GDC can also benefit from this fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, good idea
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, which Phobos changes? And IMO real.mant_dig
is all we need, as used in e.g. https://github.com/dlang/phobos/blob/c5d074b12e1038389401baa8c48c332fac5521e0/std/math/traits.d#L898-L1050
@@ -570,6 +570,8 @@ version (LDC) | |||
|
|||
version (AArch64) version = CheckFiberMigration; | |||
|
|||
version (PPC64) version = CheckFiberMigration; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
intended change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is intended change. I fixed this after running the basic unit tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To add to my last comment, that issue was not discovered because the D Phobos
library needs IEEE 128-bit arithmetic to work, which was not implemented before this pull request.
would be good to add a lit testcase for setting this abi param |
Will do |
Thanks! I have proposed a fix to the LLVM upstream regarding this issue: llvm/llvm-project#125776 |
This will allow the user to specify -mabi=ieeelongdouble + -mabi=elfv1 together without changing how LDC parses mabi options too much
9b8fd56
to
2361ed6
Compare
Corresponding DMD pull request: dlang/dmd#20826 |
This pull request adds an option to use IEEE long double ABI on Linux (if the host environment supports it).
Some adjustments are made to accommodate the new ABI (glibc uses dual-ABI in this case, where new IEEE long double-capable functions are suffixed with
__ieee128
; older functions using IBM long double are also kept for compatibility reasons).