diff options
Diffstat (limited to 'src/literal.h')
-rw-r--r-- | src/literal.h | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/src/literal.h b/src/literal.h index ffd565c71..9d9630ec4 100644 --- a/src/literal.h +++ b/src/literal.h @@ -706,6 +706,29 @@ struct GCData { GCData(HeapType type, Literals values) : type(type), values(values) {} }; +// Wasm has nondeterministic rules for NaN propagation in some operations. For +// example. f32.neg is deterministic and just flips the sign, even of a NaN, but +// f32.add is nondeterministic, and if one or more of the inputs is a NaN, then +// +// * if all NaNs are canonical NaNs, the output is some arbitrary canonical NaN +// * otherwise the output is some arbitrary arithmetic NaN +// +// (canonical = NaN payload is 1000..000; arithmetic: 1???..???, that is, the +// high bit is 1 and all others can be 0 or 1) +// +// For many things we don't need to care, and can just do a normal C++ add for +// an f32.add, for example - the wasm rules are specified so that things like +// that just work (in order for such math to be fast). However, for our +// optimizer, it is useful to "standardize" NaNs when there is nondeterminism. +// That is, when there are multiple valid outputs, it's nice to emit the same +// one consistently, so that it doesn't look like the optimization changed +// something. In other words, if the valid output of an expression is a set of +// valid NaNs, and after optimization the output is still that same set, then +// the optimization is valid. And if the interpreter picks the same NaN in both +// cases from that identical set then nothing looks wrong to the fuzzer. +Literal standardizeNaN(float result); +Literal standardizeNaN(double result); + } // namespace wasm namespace std { |