Skip to content

Commit

Permalink
Fix double to unlong conversions to handle NaN (#70331)
Browse files Browse the repository at this point in the history
This was apparently fixed in 2016 on CoreCLR but no tests were added.

The generic math tests are the first things that exercise this.

Doesn't fail in the CI because this helper is likely not needed on ARM64 and we only test libs with NativeAOT on ARM64.

Thought this was because of my local changes (because the CI was clean) but wasn't. Spent more time on this than I would be willing to admit.
  • Loading branch information
MichalStrehovsky authored Jun 7, 2022
1 parent 17d6d50 commit 88c118f
Showing 2 changed files with 50 additions and 1 deletion.
29 changes: 29 additions & 0 deletions src/coreclr/nativeaot/Runtime/CommonMacros.h
Original file line number Diff line number Diff line change
@@ -250,4 +250,33 @@ typedef int32_t HRESULT;
#endif // !defined(_INC_WINDOWS)
#endif // __GCENV_BASE_INCLUDED__

// PAL Numbers
// Used to ensure cross-compiler compatibility when declaring large
// integer constants. 64-bit integer constants should be wrapped in the
// declarations listed here.
//
// Each of the #defines here is wrapped to avoid conflicts with pal.h.

#if defined(_MSC_VER)

// MSVC's way of declaring large integer constants
// If you define these in one step, without the _HELPER macros, you
// get extra whitespace when composing these with other concatenating macros.
#ifndef I64
#define I64_HELPER(x) x ## i64
#define I64(x) I64_HELPER(x)
#endif

#else

// GCC's way of declaring large integer constants
// If you define these in one step, without the _HELPER macros, you
// get extra whitespace when composing these with other concatenating macros.
#ifndef I64
#define I64_HELPER(x) x ## LL
#define I64(x) I64_HELPER(x)
#endif

#endif

#endif // __COMMONMACROS_H__
22 changes: 21 additions & 1 deletion src/coreclr/nativeaot/Runtime/MathHelpers.cpp
Original file line number Diff line number Diff line change
@@ -9,9 +9,29 @@
// Floating point and 64-bit integer math helpers.
//

FORCEINLINE int64_t FastDbl2Lng(double val)
{
#ifdef TARGET_X86
return HCCALL1_V(JIT_Dbl2Lng, val);
#else
return((__int64) val);
#endif
}

EXTERN_C NATIVEAOT_API uint64_t REDHAWK_CALLCONV RhpDbl2ULng(double val)
{
return((uint64_t)val);
const double two63 = 2147483648.0 * 4294967296.0;
uint64_t ret;
if (val < two63)
{
ret = FastDbl2Lng(val);
}
else
{
// subtract 0x8000000000000000, do the convert then add it back again
ret = FastDbl2Lng(val - two63) + I64(0x8000000000000000);
}
return ret;
}

#undef min

0 comments on commit 88c118f

Please sign in to comment.