diff options
Diffstat (limited to 'src/passes/OptimizeInstructions.cpp')
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 106bfea19..59b1130d1 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -406,6 +406,31 @@ struct OptimizeInstructions } } { + if (getModule()->features.hasSignExt()) { + Const *c1, *c2; + Expression* x; + // i64(x) << 56 >> 56 ==> i64.extend8_s(x) + // i64(x) << 48 >> 48 ==> i64.extend16_s(x) + // i64(x) << 32 >> 32 ==> i64.extend32_s(x) + if (matches(curr, + binary(ShrSInt64, + binary(ShlInt64, any(&x), i64(&c1)), + i64(&c2))) && + Bits::getEffectiveShifts(c1) == Bits::getEffectiveShifts(c2)) { + switch (64 - Bits::getEffectiveShifts(c1)) { + case 8: + return replaceCurrent(builder.makeUnary(ExtendS8Int64, x)); + case 16: + return replaceCurrent(builder.makeUnary(ExtendS16Int64, x)); + case 32: + return replaceCurrent(builder.makeUnary(ExtendS32Int64, x)); + default: + break; + } + } + } + } + { // unsigned(x) >= 0 => i32(1) Const* c; Expression* x; @@ -792,6 +817,18 @@ struct OptimizeInstructions } } { + // i32.wrap_i64(i64.extend_i32_s(x)) => x + // i32.wrap_i64(i64.extend_i32_u(x)) => x + Unary* inner; + Expression* x; + if (matches(curr, + unary(WrapInt64, unary(&inner, ExtendSInt32, any(&x)))) || + matches(curr, + unary(WrapInt64, unary(&inner, ExtendUInt32, any(&x))))) { + return replaceCurrent(x); + } + } + { // i32.eqz(i32.wrap_i64(x)) => i64.eqz(x) // where maxBits(x) <= 32 Unary* inner; @@ -803,6 +840,20 @@ struct OptimizeInstructions return replaceCurrent(inner); } } + { + Unary* inner; + 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); + } + } + } } if (curr->op == EqZInt32) { |