This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git
The following commit(s) were added to refs/heads/main by this push:
new 420b847034 [FFI] Fix JSON parser/writer for the fast-math flag (#18221)
420b847034 is described below
commit 420b84703401d1d9fe99cb42568a3edca644975e
Author: Ruihang Lai <[email protected]>
AuthorDate: Fri Aug 22 08:02:38 2025 -0400
[FFI] Fix JSON parser/writer for the fast-math flag (#18221)
This PR fixes the JSON parser and writer for the support of the
fast-math flag.
Prior to this PR, there would be the following error when compiling
TVM with fast-math. This PR fixes this issue.
```
/home/ruihangl/Workspace/tvm/ffi/src/ffi/extra/json_writer.cc: In static
member function ‘static bool
tvm::ffi::json::JSONWriter::FastMathSafeIsNaN(double)’:
/home/ruihangl/Workspace/tvm/ffi/src/ffi/extra/json_writer.cc:69:22: error:
dereferencing type-punned pointer will break strict-aliasing rules
[-Werror=strict-aliasing]
69 | uint64_t bits = *reinterpret_cast<const uint64_t*>(&x);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ruihangl/Workspace/tvm/ffi/src/ffi/extra/json_writer.cc: In static
member function ‘static bool
tvm::ffi::json::JSONWriter::FastMathSafeIsInf(double)’:
/home/ruihangl/Workspace/tvm/ffi/src/ffi/extra/json_writer.cc:84:22: error:
dereferencing type-punned pointer will break strict-aliasing rules
[-Werror=strict-aliasing]
84 | uint64_t bits = *reinterpret_cast<const uint64_t*>(&x);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
---
ffi/src/ffi/extra/json_parser.cc | 24 ++++++++++++++++++------
ffi/src/ffi/extra/json_writer.cc | 14 ++++++++++++--
2 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/ffi/src/ffi/extra/json_parser.cc b/ffi/src/ffi/extra/json_parser.cc
index 3107e4ddf1..8bd372699d 100644
--- a/ffi/src/ffi/extra/json_parser.cc
+++ b/ffi/src/ffi/extra/json_parser.cc
@@ -298,8 +298,12 @@ class JSONParserContext {
private:
static double FastMathSafePosInf() {
#ifdef __FAST_MATH__
- const uint64_t inf_bits = 0x7FF0000000000000ULL;
- return *reinterpret_cast<const double*>(&inf_bits);
+ union {
+ uint64_t from;
+ double to;
+ } u;
+ u.from = 0x7FF0000000000000ULL; // write "from", read "to"
+ return u.to;
#else
return std::numeric_limits<double>::infinity();
#endif
@@ -307,8 +311,12 @@ class JSONParserContext {
static double FastMathSafeNegInf() {
#ifdef __FAST_MATH__
- const uint64_t inf_bits = 0xFFF0000000000000ULL;
- return *reinterpret_cast<const double*>(&inf_bits);
+ union {
+ uint64_t from;
+ double to;
+ } u;
+ u.from = 0xFFF0000000000000ULL; // write "from", read "to"
+ return u.to;
#else
return -std::numeric_limits<double>::infinity();
#endif
@@ -316,8 +324,12 @@ class JSONParserContext {
static double FastMathSafeNaN() {
#ifdef __FAST_MATH__
- const uint64_t nan_bits = 0x7FF8000000000000ULL;
- return *reinterpret_cast<const double*>(&nan_bits);
+ union {
+ uint64_t from;
+ double to;
+ } u;
+ u.from = 0x7FF8000000000000ULL; // write "from", read "to"
+ return u.to;
#else
return std::numeric_limits<double>::quiet_NaN();
#endif
diff --git a/ffi/src/ffi/extra/json_writer.cc b/ffi/src/ffi/extra/json_writer.cc
index 81d321d9a7..c2cd3f2f36 100644
--- a/ffi/src/ffi/extra/json_writer.cc
+++ b/ffi/src/ffi/extra/json_writer.cc
@@ -66,7 +66,12 @@ class JSONWriter {
// IEEE 754 standard: https://en.wikipedia.org/wiki/IEEE_754
// NaN is encoded as all 1s in the exponent and non-zero in the mantissa
static_assert(sizeof(double) == sizeof(uint64_t), "Unexpected double
size");
- uint64_t bits = *reinterpret_cast<const uint64_t*>(&x);
+ union {
+ double from;
+ uint64_t to;
+ } u;
+ u.from = x; // write "from", read "to"
+ uint64_t bits = u.to;
uint64_t exponent = (bits >> 52) & 0x7FF;
uint64_t mantissa = bits & 0xFFFFFFFFFFFFFull;
return (exponent == 0x7FF) && (mantissa != 0);
@@ -81,7 +86,12 @@ class JSONWriter {
// IEEE 754 standard: https://en.wikipedia.org/wiki/IEEE_754
// Inf is encoded as all 1s in the exponent and zero in the mantissa
static_assert(sizeof(double) == sizeof(uint64_t), "Unexpected double
size");
- uint64_t bits = *reinterpret_cast<const uint64_t*>(&x);
+ union {
+ double from;
+ uint64_t to;
+ } u;
+ u.from = x; // write "from", read "to"
+ uint64_t bits = u.to;
uint64_t exponent = (bits >> 52) & 0x7FF;
uint64_t mantissa = bits & 0xFFFFFFFFFFFFFull;
// inf is encoded as all 1s in the exponent and zero in the mantissa