summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/OptimizeInstructions.cpp17
-rw-r--r--test/lit/passes/optimize-instructions.wast60
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