From e67d50d5a6290ec9968344ee5712ebf62847fea8 Mon Sep 17 00:00:00 2001 From: Max Graey Date: Tue, 20 Jul 2021 22:28:07 +0300 Subject: [Optimize Instructions] Simplify sign extentions (#4004) requiring sign-extension: ``` i64(x) << 56 >> 56 ==> i64.extend8_s(x) i64(x) << 48 >> 48 ==> i64.extend16_s(x) i64(x) << 32 >> 32 ==> i64.extend32_s(x) i64.extend_i32_s(i32.wrap_i64(x)) ==> i64.extend32_s(x) ``` general: ``` i32.wrap_i64(i64.extend_i32_s(x)) ==> x i32.wrap_i64(i64.extend_i32_u(x)) ==> x ``` --- src/passes/OptimizeInstructions.cpp | 51 +++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'src') 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 @@ -405,6 +405,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; @@ -791,6 +816,18 @@ struct OptimizeInstructions return replaceCurrent(curr); } } + { + // 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 @@ -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) { -- cgit v1.2.3