Skip to content
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

fix issue 17243 - std.math.{FloatingPointControl,ieeeFlags} don't work on x86_64 #5240

Merged
merged 1 commit into from
Mar 14, 2017

Conversation

aG0aep6G
Copy link
Contributor

@aG0aep6G aG0aep6G commented Mar 4, 2017

I'm far from being an expert on this stuff. I learned about the different control registers only when investigating this issue here. If someone more experienced wants to take over, be my guest.

I have a test file for unmasked exceptions, but I don't know how to incorporate it into the phobos tests.

A test for roundToNearest is missing, because I'm having a hard time thinking of one.

@dlang-bot
Copy link
Contributor

dlang-bot commented Mar 4, 2017

Fix Bugzilla Description
17243 std.math.{FloatingPointControl,ieeeFlags} don't work on x86_64

@aG0aep6G aG0aep6G changed the base branch from master to stable March 4, 2017 15:31
@aG0aep6G aG0aep6G force-pushed the FloatingPointControl branch 2 times, most recently from 1884212 to 624b23f Compare March 4, 2017 15:50
@aG0aep6G aG0aep6G changed the title fix issue 17243 - std.math.FloatingPointControl doesn't work on x86_64 fix issue 17243 - std.math.{FloatingPointControl,ieeeFlags} don't work on x86_64 Mar 4, 2017
@aG0aep6G
Copy link
Contributor Author

aG0aep6G commented Mar 4, 2017

It's my understanding that the issue can also manifest on 32-bit x86s when the compiler is configured to emit SSE instructions (not sure if that can be done with dmd).There doesn't seem to be a version for SSE, so I don't know how to approach that variant of the issue.


The failures of the doc tester and CircleCI don't make sense to me. The doc tester says:

../phobos/std/traits.d(6620): Error: static assert "Type uint does not have an Unsigned counterpart"

And CircleCI says:

out/std_regex_package.d(43): Error: undefined identifier 'popFrontN'

Both seem unrelated.

@ghost
Copy link

ghost commented Mar 5, 2017

It's my understanding that the issue can also manifest on 32-bit x86s when the compiler is configured to emit SSE instructions (not sure if that can be done with dmd)

On x86, even if for rounding DMD emitts code for the FPU one may use the std.math API and write custom asm SSE code that relies on it, hence both FPU and SSE flags should be set. (IMO, this can be discussed)

@aG0aep6G aG0aep6G force-pushed the FloatingPointControl branch 2 times, most recently from d1aebd5 to 1bf8837 Compare March 5, 2017 19:10
@aG0aep6G
Copy link
Contributor Author

aG0aep6G commented Mar 5, 2017

On x86, even if for rounding DMD emitts code for the FPU one may use the std.math API and write custom asm SSE code that relies on it, hence both FPU and SSE flags should be set.

I've added a fallback to CPUID for x86.


From my end, this is good to go. I've fixed the test failures and squashed the fixup commits. auto-tester is green (pending testing of the fallback mentioned above).

@@ -155,6 +155,18 @@ else version(D_InlineAsm_X86_64)
version = InlineAsm_X86_Any;
}

version (X86_64) version = StaticallyHaveSSE;
version (X86) version (OSX) version = StaticallyHaveSSE;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is correct. Does OSX require SSE? This is here, because I've noticed that dmd emits SSE code for 32-bit OSX.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's b/c Apple only ever sold x86_64 CPUs.

std/math.d Outdated
INVALID_MASK = 0x01
}
// Don't bother about subnormals, they are not supported on most CPUs.
// SUBNORMAL_MASK = 0x02;
Copy link
Contributor Author

@aG0aep6G aG0aep6G Mar 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment seemed bogus. My run-of-the-mill AMD CPU and the auto-tester ones apparently support it.

std/math.d Outdated
@@ -4531,6 +4538,10 @@ public:
/// A machine NaN was generated. (example: x = real.infinity * 0.0; )
@property bool invalid() { return (flags & INVALID_MASK) != 0; }

/** A subnormal number was used in a calculation.
(example: x = real.min_normal / 2 + 1) */
@property bool subnormal() { return (flags & SUBNORMAL_MASK) != 0; }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andralex: Adding a new method here. As far as I remember, you want to review new names.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm cool, please make const and so the others

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please make const and so the others

Made this one const. New PR for the others as it's independent from this PR: #5246

fclex;
fldcw 8[RSP];
ret;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This deleted code looks very clever. Unfortunately, there is no comment on what it achieves. The generic variant below seems to work just fine on Win64, and it's much simpler. So I'm tearing down this fence without knowing why it was put up.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was just the naked version of the asm block below, no need for that here.

@aG0aep6G
Copy link
Contributor Author

aG0aep6G commented Mar 5, 2017

auto-tester is green (pending testing of the fallback mentioned above).

Of course it went red then. Fixed getIeeeFlags and resetIeeeFlags. All green again.

std/math.d Outdated
@@ -4531,6 +4545,10 @@ public:
/// A machine NaN was generated. (example: x = real.infinity * 0.0; )
@property bool invalid() { return (flags & INVALID_MASK) != 0; }

/** A subnormal number was used in a calculation.
(example: x = real.min_normal / 2 + 1) */
@property bool subnormal() const { return (flags & SUBNORMAL_MASK) != 0; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The majority of targets don't have an exception for denormals, I don't think this should be added here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The majority of targets don't have an exception for denormals, I don't think this should be added here.

As far as I see, IeeeFlags only works on x86 and x86-64 at the moment. Everything else errors out with "not yet supported". x86(-64) are the ones that have this, right? Would it be ok if this was versioned away from the others?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I see, IeeeFlags only works on x86 and x86-64 at the moment. Everything else errors out with "not yet supported"

GDC has code for ARM as well: https://github.com/D-Programming-GDC/GDC/blob/master/libphobos/src/std/math.d#L4372 and LDC probably supports even more targets. The part of the code that has never been upstreamed is mostly GDC extended ASM so it's not useful for other compilers anyway.

We unfortunately don't have any guidelines yet how to deal with architecture specific features (there's a similar problem for cpuid). I guess we could add this function but we should at least make sure to explicitly document it as non-portable.

@aG0aep6G
Copy link
Contributor Author

aG0aep6G commented Mar 8, 2017

I've removed the new subnormal method as it's not really related to issue 17243. The method can be discussed and added separately.

I've also squashed everything into one commit. The commit list was becoming messy.

@MartinNowak MartinNowak merged commit 83e1999 into dlang:stable Mar 14, 2017
@aG0aep6G aG0aep6G deleted the FloatingPointControl branch March 14, 2017 15:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants