summaryrefslogtreecommitdiff
path: root/src/passes/OptimizeInstructions.cpp
diff options
context:
space:
mode:
authorMax Graey <maxgraey@gmail.com>2021-07-22 21:16:45 +0300
committerGitHub <noreply@github.com>2021-07-22 11:16:45 -0700
commitf01fd8cad1cb1a6a80ef12bcfc19502bd51ddf46 (patch)
tree01d39d03bf29d7750ed7493715050338f82d4881 /src/passes/OptimizeInstructions.cpp
parentb9b8d74a4c646c4df7ddad5be195cff976cf6704 (diff)
downloadbinaryen-f01fd8cad1cb1a6a80ef12bcfc19502bd51ddf46.tar.gz
binaryen-f01fd8cad1cb1a6a80ef12bcfc19502bd51ddf46.tar.bz2
binaryen-f01fd8cad1cb1a6a80ef12bcfc19502bd51ddf46.zip
[Optimize Instructions] Simplify zero/sign extentions (special case) (#4009)
For signed or unsigned extension to 64-bits after lowering from partially filled 64-bit arguments: ```rust i64.extend_i32_u(i32.wrap_i64(x)) => x // where maxBits(x) <= 32 i64.extend_i32_s(i32.wrap_i64(x)) => x // where maxBits(x) <= 31 ```
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)) {