summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/passes/OptimizeInstructions.cpp69
-rw-r--r--src/wasm.h4
2 files changed, 61 insertions, 12 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 1c2445d5d..d77db8093 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -501,30 +501,42 @@ struct OptimizeInstructions
}
// math operations on a constant power of 2 right side can be optimized
if (right->type == Type::i32) {
- uint32_t c = right->value.geti32();
- if (IsPowerOf2(c)) {
+ BinaryOp op;
+ int32_t c = right->value.geti32();
+ if (c >= 0 &&
+ (op = makeUnsignedBinaryOp(binary->op)) != InvalidBinary &&
+ Bits::getMaxBits(binary->left, this) <= 31) {
+ binary->op = op;
+ }
+ if (IsPowerOf2((uint32_t)c)) {
switch (binary->op) {
case MulInt32:
- return optimizePowerOf2Mul(binary, c);
+ return optimizePowerOf2Mul(binary, (uint32_t)c);
case RemUInt32:
- return optimizePowerOf2URem(binary, c);
+ return optimizePowerOf2URem(binary, (uint32_t)c);
case DivUInt32:
- return optimizePowerOf2UDiv(binary, c);
+ return optimizePowerOf2UDiv(binary, (uint32_t)c);
default:
break;
}
}
}
if (right->type == Type::i64) {
- uint64_t c = right->value.geti64();
- if (IsPowerOf2(c)) {
+ BinaryOp op;
+ int64_t c = right->value.geti64();
+ if (c >= 0 &&
+ (op = makeUnsignedBinaryOp(binary->op)) != InvalidBinary &&
+ Bits::getMaxBits(binary->left, this) <= 63) {
+ binary->op = op;
+ }
+ if (IsPowerOf2((uint64_t)c)) {
switch (binary->op) {
case MulInt64:
- return optimizePowerOf2Mul(binary, c);
+ return optimizePowerOf2Mul(binary, (uint64_t)c);
case RemUInt64:
- return optimizePowerOf2URem(binary, c);
+ return optimizePowerOf2URem(binary, (uint64_t)c);
case DivUInt64:
- return optimizePowerOf2UDiv(binary, c);
+ return optimizePowerOf2UDiv(binary, (uint64_t)c);
default:
break;
}
@@ -1773,6 +1785,43 @@ private:
}
}
+ BinaryOp makeUnsignedBinaryOp(BinaryOp op) {
+ switch (op) {
+ case DivSInt32:
+ return DivUInt32;
+ case RemSInt32:
+ return RemUInt32;
+ case ShrSInt32:
+ return ShrUInt32;
+ case LtSInt32:
+ return LtUInt32;
+ case LeSInt32:
+ return LeUInt32;
+ case GtSInt32:
+ return GtUInt32;
+ case GeSInt32:
+ return GeUInt32;
+
+ case DivSInt64:
+ return DivUInt64;
+ case RemSInt64:
+ return RemUInt64;
+ case ShrSInt64:
+ return ShrUInt64;
+ case LtSInt64:
+ return LtUInt64;
+ case LeSInt64:
+ return LeUInt64;
+ case GtSInt64:
+ return GtUInt64;
+ case GeSInt64:
+ return GeUInt64;
+
+ default:
+ return InvalidBinary;
+ }
+ }
+
bool isSymmetric(Binary* binary) {
if (Properties::isSymmetric(binary)) {
return true;
diff --git a/src/wasm.h b/src/wasm.h
index d2965b405..d41ad863a 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -225,8 +225,8 @@ enum BinaryOp {
OrInt32,
XorInt32,
ShlInt32,
- ShrUInt32,
ShrSInt32,
+ ShrUInt32,
RotLInt32,
RotRInt32,
@@ -258,8 +258,8 @@ enum BinaryOp {
OrInt64,
XorInt64,
ShlInt64,
- ShrUInt64,
ShrSInt64,
+ ShrUInt64,
RotLInt64,
RotRInt64,