diff options
author | Max Graey <maxgraey@gmail.com> | 2020-10-30 08:08:48 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-29 23:08:48 -0700 |
commit | 5fc27e20479edfef0674c89e9bb7888ee25cb054 (patch) | |
tree | a748191c55e48d91bbc3d01ed64e6d3de0762c66 /src/passes | |
parent | 25e47f2c3e7ca8151377075432b34c95073acaca (diff) | |
download | binaryen-5fc27e20479edfef0674c89e9bb7888ee25cb054.tar.gz binaryen-5fc27e20479edfef0674c89e9bb7888ee25cb054.tar.bz2 binaryen-5fc27e20479edfef0674c89e9bb7888ee25cb054.zip |
Fold subtraction of sums or differences from constants (#3295)
`C1 - (x + C2)` -> `(C1 - C2) - x`
`C1 - (x - C2)` -> `(C1 + C2) - x`
`C1 - (C2 - x)` -> `x + (C1 - C2)`
Diffstat (limited to 'src/passes')
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 57ef42913..20cdeee19 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -1734,6 +1734,39 @@ private: return curr->left; } { + // C1 - (x + C2) ==> (C1 - C2) - x + Const *c1, *c2; + Expression* x; + if (matches(curr, + binary(Sub, ival(&c1), binary(Add, any(&x), ival(&c2))))) { + left->value = c1->value.sub(c2->value); + curr->right = x; + return curr; + } + // C1 - (x - C2) ==> (C1 + C2) - x + if (matches(curr, + binary(Sub, ival(&c1), binary(Sub, any(&x), ival(&c2))))) { + left->value = c1->value.add(c2->value); + curr->right = x; + return curr; + } + // C1 - (C2 - x) ==> x + (C1 - C2) + if (matches(curr, + binary(Sub, ival(&c1), binary(Sub, ival(&c2), any(&x))))) { + left->value = c1->value.sub(c2->value); + if (left->value.isNegative()) { + // -C1 - (C2 - x) ==> x - (C1 - C2) + left->value = left->value.neg(); + curr->op = Abstract::getBinary(type, Sub); + } else { + curr->op = Abstract::getBinary(type, Add); + } + curr->right = x; + std::swap(curr->left, curr->right); + return curr; + } + } + { // fval(C) / -x ==> -C / x Expression* right; if (matches(curr, binary(DivS, fval(), unary(Neg, any(&right))))) { |