summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ir/properties.h5
-rw-r--r--src/passes/OptimizeInstructions.cpp27
-rw-r--r--test/passes/O4_disable-bulk-memory.txt8
-rw-r--r--test/wasm2js/conversions-modified.2asm.js.opt8
-rw-r--r--test/wasm2js/float-ops.2asm.js.opt8
5 files changed, 42 insertions, 14 deletions
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<Binary>()) {
- 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<Const>()) {
+ return !c->value.isNaN();
+ }
+ return false;
+ }
+ default:
+ return false;
+ }
+ }
};
Pass* createOptimizeInstructionsPass() { return new OptimizeInstructions(); }
diff --git a/test/passes/O4_disable-bulk-memory.txt b/test/passes/O4_disable-bulk-memory.txt
index 78c130ffb..454b23abb 100644
--- a/test/passes/O4_disable-bulk-memory.txt
+++ b/test/passes/O4_disable-bulk-memory.txt
@@ -968,8 +968,8 @@
(local.get $0)
)
(f64.mul
- (f64.const 0.01)
(local.get $4)
+ (f64.const 0.01)
)
)
)
@@ -980,8 +980,8 @@
(local.get $0)
)
(f64.mul
- (f64.const 0.01)
(local.get $5)
+ (f64.const 0.01)
)
)
)
@@ -992,8 +992,8 @@
(local.get $0)
)
(f64.mul
- (f64.const 0.01)
(local.get $6)
+ (f64.const 0.01)
)
)
)
@@ -1067,12 +1067,12 @@
(local.get $1)
(f64.mul
(f64.mul
- (f64.const 0.5)
(local.tee $10
(f64.load offset=48
(local.get $0)
)
)
+ (f64.const 0.5)
)
(f64.add
(f64.add
diff --git a/test/wasm2js/conversions-modified.2asm.js.opt b/test/wasm2js/conversions-modified.2asm.js.opt
index 5efd1966d..245465e88 100644
--- a/test/wasm2js/conversions-modified.2asm.js.opt
+++ b/test/wasm2js/conversions-modified.2asm.js.opt
@@ -156,19 +156,19 @@ function asmFunc(global, env, buffer) {
}
function legalstub$12($0, $1) {
- return Math_fround(+($0 >>> 0) + 4294967296.0 * +($1 | 0));
+ return Math_fround(+($0 >>> 0) + +($1 | 0) * 4294967296.0);
}
function legalstub$14($0, $1) {
- return +($0 >>> 0) + 4294967296.0 * +($1 | 0);
+ return +($0 >>> 0) + +($1 | 0) * 4294967296.0;
}
function legalstub$16($0, $1) {
- return Math_fround(+($0 >>> 0) + 4294967296.0 * +($1 >>> 0));
+ return Math_fround(+($0 >>> 0) + +($1 >>> 0) * 4294967296.0);
}
function legalstub$18($0, $1) {
- return +($0 >>> 0) + 4294967296.0 * +($1 >>> 0);
+ return +($0 >>> 0) + +($1 >>> 0) * 4294967296.0;
}
function legalstub$22($0, $1) {
diff --git a/test/wasm2js/float-ops.2asm.js.opt b/test/wasm2js/float-ops.2asm.js.opt
index 7e3413736..17519fc2a 100644
--- a/test/wasm2js/float-ops.2asm.js.opt
+++ b/test/wasm2js/float-ops.2asm.js.opt
@@ -255,19 +255,19 @@ function asmFunc(global, env, buffer) {
}
function legalstub$43($0, $1_1) {
- return Math_fround(+($0 >>> 0) + 4294967296.0 * +($1_1 | 0));
+ return Math_fround(+($0 >>> 0) + +($1_1 | 0) * 4294967296.0);
}
function legalstub$44($0, $1_1) {
- return +($0 >>> 0) + 4294967296.0 * +($1_1 | 0);
+ return +($0 >>> 0) + +($1_1 | 0) * 4294967296.0;
}
function legalstub$45($0, $1_1) {
- return Math_fround(+($0 >>> 0) + 4294967296.0 * +($1_1 >>> 0));
+ return Math_fround(+($0 >>> 0) + +($1_1 >>> 0) * 4294967296.0);
}
function legalstub$46($0, $1_1) {
- return +($0 >>> 0) + 4294967296.0 * +($1_1 >>> 0);
+ return +($0 >>> 0) + +($1_1 >>> 0) * 4294967296.0;
}
var FUNCTION_TABLE = [];