diff options
author | Max Graey <maxgraey@gmail.com> | 2020-09-15 06:44:43 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-14 20:44:43 -0700 |
commit | bcc6f2994e8f71b633b1d0257547aeed691f6ceb (patch) | |
tree | 8655674f0f9d513cc79a4b3ec9074c3b77ccebf7 /src | |
parent | 18716065cc470c3bc29a4fecf3889891a9bf604b (diff) | |
download | binaryen-bcc6f2994e8f71b633b1d0257547aeed691f6ceb.tar.gz binaryen-bcc6f2994e8f71b633b1d0257547aeed691f6ceb.tar.bz2 binaryen-bcc6f2994e8f71b633b1d0257547aeed691f6ceb.zip |
Add float operations for isSymmetric util (#3127)
Add floating point Eq and Ne operators to Properties::isSymmetric. Also treat additional float ops as symmetric specifically in OptimizeInstructions when their operands are known to be non-NaN.
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/properties.h | 5 | ||||
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 27 |
2 files changed, 30 insertions, 2 deletions
diff --git a/src/ir/properties.h b/src/ir/properties.h index f38773bd8..56723631a 100644 --- a/src/ir/properties.h +++ b/src/ir/properties.h @@ -51,6 +51,11 @@ inline bool isSymmetric(Binary* binary) { case XorInt64: case EqInt64: case NeInt64: + + case EqFloat32: + case NeFloat32: + case EqFloat64: + case NeFloat64: return true; default: diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 676e753ce..04661af2d 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -202,7 +202,7 @@ struct OptimizeInstructions return nullptr; } if (auto* binary = curr->dynCast<Binary>()) { - if (Properties::isSymmetric(binary)) { + if (isSymmetric(binary)) { canonicalize(binary); } if (auto* ext = Properties::getAlmostSignExt(binary)) { @@ -731,7 +731,7 @@ private: // Canonicalizing the order of a symmetric binary helps us // write more concise pattern matching code elsewhere. void canonicalize(Binary* binary) { - assert(Properties::isSymmetric(binary)); + assert(isSymmetric(binary)); FeatureSet features = getModule()->features; auto swap = [&]() { assert(EffectAnalyzer::canReorder( @@ -1591,6 +1591,29 @@ private: return InvalidBinary; } } + + bool isSymmetric(Binary* binary) { + if (Properties::isSymmetric(binary)) { + return true; + } + switch (binary->op) { + case AddFloat32: + case MulFloat32: + case AddFloat64: + case MulFloat64: { + // If the LHS is known to be non-NaN, the operands can commute. + // We don't care about the RHS because right now we only know if + // an expression is non-NaN if it is constant, but if the RHS is + // constant, then this expression is already canonicalized. + if (auto* c = binary->left->dynCast<Const>()) { + return !c->value.isNaN(); + } + return false; + } + default: + return false; + } + } }; Pass* createOptimizeInstructionsPass() { return new OptimizeInstructions(); } |