summaryrefslogtreecommitdiff
path: root/src/passes/OptimizeInstructions.cpp
diff options
context:
space:
mode:
authorMax Graey <maxgraey@gmail.com>2022-09-12 23:42:16 +0300
committerGitHub <noreply@github.com>2022-09-12 13:42:16 -0700
commitc7967d81d2d5ed06440044d45ad52158c40ee168 (patch)
treee788fb67bc87ca859845d6813aac4ba29af4af45 /src/passes/OptimizeInstructions.cpp
parentaa36fc4f67cf38f097b4c2b4db53b718880f9c3a (diff)
downloadbinaryen-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.cpp34
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;
}