summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMax Graey <maxgraey@gmail.com>2020-09-15 06:44:43 +0300
committerGitHub <noreply@github.com>2020-09-14 20:44:43 -0700
commitbcc6f2994e8f71b633b1d0257547aeed691f6ceb (patch)
tree8655674f0f9d513cc79a4b3ec9074c3b77ccebf7 /src
parent18716065cc470c3bc29a4fecf3889891a9bf604b (diff)
downloadbinaryen-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.h5
-rw-r--r--src/passes/OptimizeInstructions.cpp27
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(); }