Fix __FINITE_MATH_ONLY__ guard to test the value, not definedness - #338
Draft
sivadeilra wants to merge 1 commit into
Draft
Fix __FINITE_MATH_ONLY__ guard to test the value, not definedness#338sivadeilra wants to merge 1 commit into
sivadeilra wants to merge 1 commit into
Conversation
XMVectorIsNaN, XMVector2IsNaN, XMVector3IsNaN and XMVector4IsNaN each guard a
scalar fallback with:
#if defined(__clang__) && defined(__FINITE_MATH_ONLY__)
but clang defines __FINITE_MATH_ONLY__ unconditionally -- 0 by default, and 1
only under -ffast-math / -ffinite-math-only (clang-cl /fp:fast). The guard is
therefore always true under clang, so the fallback is compiled into every clang
build instead of only finite-math ones.
Two consequences:
- The fallback calls unqualified isnan(), so any clang target whose C++ library
does not declare isnan() fails to compile. This is how the bug surfaced.
- Where it does compile, a single vector compare is replaced by a store, four
scalar tests and a reassemble.
Test the macro's value instead. Verified with clang-cl that the guard is now
false at the default /fp:precise and still true under /fp:fast.
Affects both the NEON and SSE paths of all four functions (8 sites).
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Collaborator
|
@sivadeilra For MSVC, a pragma turns off There is a bug where some older versions of MSVC ignored this pragma for inline code, but that is fixed in updates. Are you using |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Problem
XMVectorIsNaN,XMVector2IsNaN,XMVector3IsNaNandXMVector4IsNaNeach guard a scalar fallback with:Clang defines
__FINITE_MATH_ONLY__unconditionally —0by default, and1only under-ffast-math/-ffinite-math-only(clang-cl/fp:fast). The guard tests definedness rather than the value, so it is always true under clang and the fallback is compiled into every clang build, not just finite-math ones.Measured with clang-cl:
__FINITE_MATH_ONLY__/fp:precise)/fp:fastConsequences
isnan(). Any clang target whose C++ library does not declareisnan()fails to compile. This is how we hit it: ~690 errors across 35 build directories in the Windows source tree, alluse of undeclared identifier 'isnan'at these sites.MSVC never defines the macro, so it always takes the intrinsic path — which is why this is clang-only.
Change
Tests the macro's value instead. 8 sites: 4 functions × the NEON and SSE paths of each. No other file in the repo references the macro.
Preserves the file's CRLF line endings and ASCII-only content per
.editorconfig.Open question for maintainers
While investigating I measured what actually happens under
/fp:fast, i.e. the only configuration in which the fallback is now selected. Under clang, every scalar NaN test folds to constantfalsethere —__builtin_isnan,x != x, and even explicit union bit-inspection of the exponent field all becomexor eax,eax; ret, becausennan/ninflet the optimizer prove no NaN can occur.If that holds generally, the fallback does not do anything even when correctly selected, and deleting it may be more honest than re-guarding it. I have kept this PR to the minimal, clearly-correct fix and am raising the broader question rather than acting on it, since it is a behavioural decision for the maintainers.
Related: MSVC folds
_mm_cmpneq_ps(V, V)to an all-zero mask under/fp:fastas well, soXMVectorIsNaNalready returns "no lane is NaN" in fast-math MSVC builds. That is independent of this change.