diff options
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(); } |