-
Notifications
You must be signed in to change notification settings - Fork 34
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
test: Fix comparing of floating point results in spectest runner #460
Conversation
Codecov Report
@@ Coverage Diff @@
## master #460 +/- ##
=======================================
Coverage 99.51% 99.51%
=======================================
Files 54 54
Lines 15120 15153 +33
=======================================
+ Hits 15046 15079 +33
Misses 74 74 |
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.
Any smoketests additions?
test/spectests/spectests.cpp
Outdated
bool float_values_equal(fizzy::Value value1, fizzy::Value value2) noexcept | ||
{ | ||
if (std::isnan(value1.as<float>())) | ||
return value1.as<uint32_t>() == value2.as<uint32_t>(); // compare binary representations |
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.
This is quite close to undefined behavior: only single union member may be active at any point in time and you are allowed to only access the active one. Here you are accessing two members is a row - one of the accesses must be wrong.
But also to simplify: you can always compare binary representation of floats. I would just leave return value1.as<uint32_t>() == value2.as<uint32_t>();
.
Also: add the following check in value.hpp
: static_assert(offsetof(Value, f32) == offsetof(Value, i32));
.
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.
(now I see why you needed to_uint64
/from_uint64
)
Well ok, then the current way here it will be UB only for NaN case, but if I do always as<uint32_t>()
then always...
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.
That's actually not true, because you always set i64
to active in read_value()
. In theory, you are never allowed to access f32
nor f64
. But I doubt this will cause issues in practice. However, I had issues with performing type punning using unions in GCC before (when the misuse is obvious, in the same function).
But my motivation to always use "binary" representation for comparison is to make sure this is a reliable method and there are no regressions in running spectests.
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.
This was replaced to comparison using FP
utility from #454
35c33d6
to
70ca840
Compare
No spectests results change is expected here? |
No, I guess because all NaN tests are skipped on master so far. |
70ca840
to
aaf1127
Compare
f1de6c7
to
d8d44aa
Compare
ca41f68
to
d204758
Compare
const uint64_t uint_value = std::stoull(v.at("value").get<std::string>()); | ||
|
||
if (type == "i32" || type == "i64") | ||
return uint_value; |
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 decided for now not to complicate it with checking if the value declared as 32-bit is really not wider. It won't result in UB if it happens.
b9f3a27
to
ee2d12e
Compare
8c71f3e
to
2b35f84
Compare
bd36d5e
to
2196c0a
Compare
2196c0a
to
ad1bee0
Compare
ad1bee0
to
2ef71c1
Compare
@@ -40,9 +40,15 @@ | |||
;; invalid result | |||
(module | |||
(func (export "foo.i32") (result i32) (i32.const 1)) | |||
(func (export "foo.i64") (result i64) (i64.const 1)) | |||
(func (export "foo.f32") (result f32) (f32.const 1)) | |||
(func (export "foo.f64") (result f64) (f64.const 1)) |
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 it would be better to use actual floats for these, to be sure. Such as 1.234.
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.
Changed
if (arg_type != "i32" && arg_type != "i64" && arg_type != "f32" && arg_type != "f64") | ||
const auto type = v.at("type").get<std::string>(); | ||
|
||
// JSON tests have all values including floats serialized as 64-bit unsigned integers |
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.
Not that JSON supports the whole 64-bit 😉
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.
The format supports arbitrary long literals, in theory.
2ef71c1
to
6c48a0e
Compare
No description provided.