diff options
author | Max Graey <maxgraey@gmail.com> | 2020-10-28 01:52:04 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-27 16:52:04 -0700 |
commit | 8fd93ee74150a8783c5118ea9804b508fe67701f (patch) | |
tree | eb1cba21a9eeb41fafe38740e6d3e905ffec3775 /src | |
parent | 5c31f461afe87088e1e0972dbcbf0507c15b2880 (diff) | |
download | binaryen-8fd93ee74150a8783c5118ea9804b508fe67701f.tar.gz binaryen-8fd93ee74150a8783c5118ea9804b508fe67701f.tar.bz2 binaryen-8fd93ee74150a8783c5118ea9804b508fe67701f.zip |
Propagate sign to constants for float point expressions (#3289)
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 89315ab60..c7219dd3c 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -1684,6 +1684,14 @@ private: return curr->left; } } + // -x * fval(C) ==> x * -C + // -x / fval(C) ==> x / -C + if (matches(curr, binary(Mul, unary(Neg, any(&left)), fval())) || + matches(curr, binary(DivS, unary(Neg, any(&left)), fval()))) { + right->value = right->value.neg(); + curr->left = left; + return curr; + } // x * -1.0 ==> -x if (fastMath && matches(curr, binary(Mul, any(), fval(-1.0)))) { return builder.makeUnary(Abstract::getUnary(type, Neg), left); @@ -1702,18 +1710,23 @@ private: // is a constant. since we canonicalize constants to the right for symmetrical // operations, we only need to handle asymmetrical ones here // TODO: templatize on type? - Expression* optimizeWithConstantOnLeft(Binary* binary) { - auto type = binary->left->type; - auto* left = binary->left->cast<Const>(); - if (type.isInteger()) { - // operations on zero - if (left->value == Literal::makeFromInt32(0, type)) { - if ((binary->op == Abstract::getBinary(type, Abstract::Shl) || - binary->op == Abstract::getBinary(type, Abstract::ShrU) || - binary->op == Abstract::getBinary(type, Abstract::ShrS)) && - !effects(binary->right).hasSideEffects()) { - return binary->left; - } + Expression* optimizeWithConstantOnLeft(Binary* curr) { + using namespace Match; + using namespace Abstract; + + auto* left = curr->left->cast<Const>(); + // 0 <<>> y ==> 0 + if (Abstract::hasAnyShift(curr->op) && left->value.isZero() && + !effects(curr->right).hasSideEffects()) { + return curr->left; + } + { + // fval(C) / -x ==> -C / x + Expression* right; + if (matches(curr, binary(DivS, fval(), unary(Neg, any(&right))))) { + left->value = left->value.neg(); + curr->right = right; + return curr; } } return nullptr; |