diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 69 | ||||
-rw-r--r-- | src/wasm.h | 4 |
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, |