diff options
author | Max Graey <maxgraey@gmail.com> | 2022-09-12 23:42:16 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-12 13:42:16 -0700 |
commit | c7967d81d2d5ed06440044d45ad52158c40ee168 (patch) | |
tree | e788fb67bc87ca859845d6813aac4ba29af4af45 /src/passes/OptimizeInstructions.cpp | |
parent | aa36fc4f67cf38f097b4c2b4db53b718880f9c3a (diff) | |
download | binaryen-c7967d81d2d5ed06440044d45ad52158c40ee168.tar.gz binaryen-c7967d81d2d5ed06440044d45ad52158c40ee168.tar.bz2 binaryen-c7967d81d2d5ed06440044d45ad52158c40ee168.zip |
[OptimizeInstructions] Simplify floating point ops with NaN on right side (#4985)
x + nan -> nan'
x - nan -> nan'
x * nan -> nan'
x / nan -> nan'
min(x, nan) -> nan'
max(x, nan) -> nan'
where nan' is canonicalized nan of rhs
x != nan -> 1
x == nan -> 0
x >= nan -> 0
x <= nan -> 0
x > nan -> 0
x < nan -> 0
Diffstat (limited to 'src/passes/OptimizeInstructions.cpp')
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 7f0b28574..9024d0cb6 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -3597,6 +3597,40 @@ private: } } } + { + // x != NaN ==> 1 + // x <=> NaN ==> 0 + // x op NaN' ==> NaN', iff `op` != `copysign` and `x` != C + Const* c; + Binary* bin; + Expression* x; + if (matches(curr, binary(&bin, pure(&x), fval(&c))) && + std::isnan(c->value.getFloat()) && + bin->op != getBinary(x->type, CopySign)) { + if (bin->isRelational()) { + // reuse "c" (nan) constant + c->type = Type::i32; + if (bin->op == getBinary(x->type, Ne)) { + // x != NaN ==> 1 + c->value = Literal::makeOne(Type::i32); + } else { + // x == NaN, + // x > NaN, + // x <= NaN + // x .. NaN ==> 0 + c->value = Literal::makeZero(Type::i32); + } + return c; + } + // propagate NaN of RHS but canonicalize it + if (c->type == Type::f32) { + c->value = standardizeNaN(c->value.getf32()); + } else { + c->value = standardizeNaN(c->value.getf64()); + } + return c; + } + } return nullptr; } |