Repository navigation
Use x87 fsqrt for rounded square roots on 32-bit MSVC #64
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
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| /* Boost test/sqrt_rounding.cpp | ||
| * the rounded square roots of the rounding policies follow the rounding mode | ||
| * | ||
| * Distributed under the Boost Software License, Version 1.0. | ||
| * (See accompanying file LICENSE_1_0.txt or | ||
| * copy at http://www.boost.org/LICENSE_1_0.txt) | ||
| */ | ||
|
|
||
| // The sqrt of the 32-bit Microsoft runtime rounds to nearest whatever the | ||
| // rounding mode, so sqrt_down and sqrt_up returned the same value there. | ||
| // | ||
| // sqrt is correctly rounded, so for a non-square x the two ends must differ, | ||
| // and for an exact square both must be the exact root. Each call reads its | ||
| // operand from volatile storage, so that GCC cannot merge the two roots of | ||
| // the same operand (a separate bug, GCC bug 34678). | ||
|
|
||
| #include <boost/numeric/interval.hpp> | ||
| #include <boost/core/lightweight_test.hpp> | ||
|
|
||
| template<class Rounding, class T> | ||
| void test_policy() | ||
| { | ||
| static volatile T non_squares[] = { 2, 3, 5, 7, 10, 1.5f, 0.75f }; | ||
| static volatile T squares[] = { 1, 4, 9, 2.25f, 0.25f }; | ||
| const int n_non = sizeof(non_squares) / sizeof(non_squares[0]); | ||
| const int n_sq = sizeof(squares) / sizeof(squares[0]); | ||
| for (int i = 0; i < n_non; ++i) { | ||
| Rounding rnd; | ||
| T a = non_squares[i]; | ||
| T dn = rnd.sqrt_down(a); | ||
| T b = non_squares[i]; | ||
| T up = rnd.sqrt_up(b); | ||
| BOOST_TEST(dn < up); | ||
| } | ||
| for (int i = 0; i < n_sq; ++i) { | ||
| Rounding rnd; | ||
| T a = squares[i]; | ||
| T dn = rnd.sqrt_down(a); | ||
| T b = squares[i]; | ||
| T up = rnd.sqrt_up(b); | ||
| T x = squares[i]; | ||
| BOOST_TEST(dn == up); | ||
| BOOST_TEST(dn * dn == x); | ||
| } | ||
| } | ||
|
|
||
| template<class T> | ||
| void test() | ||
| { | ||
| using namespace boost::numeric::interval_lib; | ||
| test_policy<save_state<rounded_arith_opp<T> >, T>(); | ||
| test_policy<save_state<rounded_arith_std<T> >, T>(); | ||
| } | ||
|
|
||
| int main() | ||
| { | ||
| test<float>(); | ||
| test<double>(); | ||
| // Only where long double has the format of double, as with MSVC. An x87 | ||
| // long double result is not yet ordered before the next mode change, which | ||
| // is a separate bug. | ||
| if (sizeof(long double) == sizeof(double)) | ||
| test<long double>(); | ||
| return boost::report_errors(); | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
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, you need to check for the
_M_IX86_FPvalue here and select between x87 and SSE2 implementations. Otherwise, you're forcing x87 when the rest of the program is using SSE2. You can use SSE2 intrinsics to calculate the sqrt. And we should probably add separate CI jobs for 32-bit x86 with/arch:IA32and/arch:SSE2.Also, since you're working around a standard library issue, you probably need to check
BOOST_DINKUMWARE_STDLIBhere.Uh oh!
There was an error while loading. Please reload this page.
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.
About
BOOST_DINKUMWARE_STDLIB- I read it needs to applied when using the c++ stdlib, but here it was using the C Runtime? there was a clang windows failure as well?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,
BOOST_DINKUMWARE_STDLIBindicates Microsoft's C++ standard library. We don't have a macro specifically for the C standard library, C++ library is the closest we have. The idea is that if there is a compiler that uses the same C runtime but does not pretend to be MSVC then it should be also affected. However, to my knowledge, all compilers using MS's C++ standard library do pretend as MSVC. MinGW gcc, which uses libstdc++ and some parts of MS's C runtime, appears to be passing in CI. I think, this is because it directly generates x87 and SSE instructions for sqrt instead of the C library calls. So this point is probably moot.