From bcc6f2994e8f71b633b1d0257547aeed691f6ceb Mon Sep 17 00:00:00 2001 From: Max Graey Date: Tue, 15 Sep 2020 06:44:43 +0300 Subject: 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. --- src/ir/properties.h | 5 +++++ src/passes/OptimizeInstructions.cpp | 27 +++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) (limited to 'src') 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()) { - 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()) { + return !c->value.isNaN(); + } + return false; + } + default: + return false; + } + } }; Pass* createOptimizeInstructionsPass() { return new OptimizeInstructions(); } -- cgit v1.2.3