diff options
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 17 | ||||
-rw-r--r-- | test/lit/passes/optimize-instructions.wast | 60 |
2 files changed, 77 insertions, 0 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 9ab8e20d9..63f47abd1 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -716,6 +716,23 @@ struct OptimizeInstructions } } } + if (left->op == Abstract::getBinary(left->type, Abstract::Shl) && + curr->op == Abstract::getBinary(curr->type, Abstract::Mul)) { + if (auto* leftRight = left->right->dynCast<Const>()) { + left->op = Abstract::getBinary(left->type, Abstract::Mul); + // (x << C1) * C2 -> x * (C2 << C1) + leftRight->value = right->value.shl(leftRight->value); + return replaceCurrent(left); + } + } + if (left->op == Abstract::getBinary(left->type, Abstract::Mul) && + curr->op == Abstract::getBinary(curr->type, Abstract::Shl)) { + if (auto* leftRight = left->right->dynCast<Const>()) { + // (x * C1) << C2 -> x * (C1 << C2) + leftRight->value = leftRight->value.shl(right->value); + return replaceCurrent(left); + } + } } if (right->type == Type::i32) { BinaryOp op; diff --git a/test/lit/passes/optimize-instructions.wast b/test/lit/passes/optimize-instructions.wast index 70e28cfd6..6e69a7baf 100644 --- a/test/lit/passes/optimize-instructions.wast +++ b/test/lit/passes/optimize-instructions.wast @@ -5969,6 +5969,66 @@ (i32.const -1024) ) ) + ;; CHECK: (func $optimizeAddedConstants-mul-lshift-32 (param $x i32) (result i32) + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $optimizeAddedConstants-mul-lshift-32 (param $x i32) (result i32) + (i32.shl + (i32.mul + (local.get $x) + (i32.const 3) + ) + (i32.const 2) + ) + ) + ;; CHECK: (func $optimizeAddedConstants-mul-lshift-64 (param $x i64) (result i64) + ;; CHECK-NEXT: (i64.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i64.const 12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $optimizeAddedConstants-mul-lshift-64 (param $x i64) (result i64) + (i64.shl + (i64.mul + (local.get $x) + (i64.const 3) + ) + (i64.const 2) + ) + ) + ;; CHECK: (func $optimizeAddedConstants-lshift-mul-32 (param $x i32) (result i32) + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $optimizeAddedConstants-lshift-mul-32 (param $x i32) (result i32) + (i32.mul + (i32.shl + (local.get $x) + (i32.const 2) + ) + (i32.const 3) + ) + ) + ;; CHECK: (func $optimizeAddedConstants-lshift-mul-64 (param $x i64) (result i64) + ;; CHECK-NEXT: (i64.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i64.const 12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $optimizeAddedConstants-lshift-mul-64 (param $x i64) (result i64) + (i64.mul + (i64.shl + (local.get $x) + (i64.const 2) + ) + (i64.const 3) + ) + ) ;; CHECK: (func $return-proper-value-from-shift-left-by-zero (result i32) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.add |