summaryrefslogtreecommitdiff
path: root/src/passes/OptimizeInstructions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/OptimizeInstructions.cpp')
-rw-r--r--src/passes/OptimizeInstructions.cpp34
1 files changed, 25 insertions, 9 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 31ed9348a..2e6a2d48d 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -841,19 +841,35 @@ struct OptimizeInstructions
}
}
{
- Unary* inner;
+ // i64.extend_i32_s(i32.wrap_i64(x)) => x
+ // where maxBits(x) <= 31
+ //
+ // i64.extend_i32_u(i32.wrap_i64(x)) => x
+ // where maxBits(x) <= 32
Expression* x;
- if (getModule()->features.hasSignExt()) {
- // i64.extend_i32_s(i32.wrap_i64(x)) => i64.extend32_s(x)
- if (matches(curr,
- unary(ExtendSInt32, unary(&inner, WrapInt64, any(&x))))) {
- inner->op = ExtendS32Int64;
- inner->type = Type::i64;
- inner->value = x;
- return replaceCurrent(inner);
+ UnaryOp unaryOp;
+ if (matches(curr, unary(&unaryOp, unary(WrapInt64, any(&x))))) {
+ if (unaryOp == ExtendSInt32 || unaryOp == ExtendUInt32) {
+ auto maxBits = Bits::getMaxBits(x, this);
+ if ((unaryOp == ExtendSInt32 && maxBits <= 31) ||
+ (unaryOp == ExtendUInt32 && maxBits <= 32)) {
+ return replaceCurrent(x);
+ }
}
}
}
+ if (getModule()->features.hasSignExt()) {
+ // i64.extend_i32_s(i32.wrap_i64(x)) => i64.extend32_s(x)
+ Unary* inner;
+ Expression* x;
+ if (matches(curr,
+ unary(ExtendSInt32, unary(&inner, WrapInt64, any(&x))))) {
+ inner->op = ExtendS32Int64;
+ inner->type = Type::i64;
+ inner->value = x;
+ return replaceCurrent(inner);
+ }
+ }
}
if (Abstract::hasAnyReinterpret(curr->op)) {