From 815f97aab7df999c3f02307a715690f958e424da Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Mon, 19 Oct 2020 18:26:28 +0300 Subject: [PATCH 1/5] init --- src/compiler.ts | 35 +++++++++++++++++----- tests/compiler/abi.untouched.wat | 2 ++ tests/compiler/retain-i32.ts | 4 +-- tests/compiler/retain-i32.untouched.wat | 8 +++++ tests/compiler/std/dataview.untouched.wat | 8 +++++ tests/compiler/std/polyfills.untouched.wat | 16 ++++++++++ 6 files changed, 63 insertions(+), 10 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index 01914289ac..9c965446fe 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -5128,7 +5128,7 @@ export class Compiler extends DiagnosticEmitter { module.binary(BinaryOp.EqI8x16, leftExpr, rightExpr) ); } - case TypeKind.FUNCREF: + case TypeKind.FUNCREF: case TypeKind.EXTERNREF: case TypeKind.EXNREF: case TypeKind.ANYREF: { @@ -5648,7 +5648,14 @@ export class Compiler extends DiagnosticEmitter { case TypeKind.I8: case TypeKind.I16: case TypeKind.U8: - case TypeKind.U16: + case TypeKind.U16: { + // leftExpr << (rightExpr & (7|15)) + return module.binary( + BinaryOp.ShlI32, + leftExpr, + module.binary(BinaryOp.AndI32, rightExpr, module.i32(type.size - 1)) + ); + } case TypeKind.I32: case TypeKind.U32: { return module.binary(BinaryOp.ShlI32, leftExpr, rightExpr); @@ -5679,8 +5686,12 @@ export class Compiler extends DiagnosticEmitter { switch (type.kind) { case TypeKind.I8: case TypeKind.I16: { - leftExpr = this.ensureSmallIntegerWrap(leftExpr, type); - // falls through + // leftExpr >> (rightExpr & (7 | 15)) + return module.binary( + BinaryOp.ShrI32, + this.ensureSmallIntegerWrap(leftExpr, type), + module.binary(BinaryOp.AndI32, rightExpr, module.i32(type.size - 1)) + ); } case TypeKind.I32: { return module.binary(BinaryOp.ShrI32, leftExpr, rightExpr); @@ -5703,8 +5714,12 @@ export class Compiler extends DiagnosticEmitter { } case TypeKind.U8: case TypeKind.U16: { - leftExpr = this.ensureSmallIntegerWrap(leftExpr, type); - // falls through + // leftExpr >>> (rightExpr & (7 | 15)) + return module.binary( + BinaryOp.ShrU32, + this.ensureSmallIntegerWrap(leftExpr, type), + module.binary(BinaryOp.AndI32, rightExpr, module.i32(type.size - 1)) + ); } case TypeKind.U32: { return module.binary(BinaryOp.ShrU32, leftExpr, rightExpr); @@ -5738,8 +5753,12 @@ export class Compiler extends DiagnosticEmitter { case TypeKind.I16: case TypeKind.U8: case TypeKind.U16: { - leftExpr = this.ensureSmallIntegerWrap(leftExpr, type); - // falls through + // leftExpr >>> (rightExpr & (7 | 15)) + return module.binary( + BinaryOp.ShrU32, + this.ensureSmallIntegerWrap(leftExpr, type), + module.binary(BinaryOp.AndI32, rightExpr, module.i32(type.size - 1)) + ); } case TypeKind.I32: case TypeKind.U32: { diff --git a/tests/compiler/abi.untouched.wat b/tests/compiler/abi.untouched.wat index f540d255b1..d87a34b2b3 100644 --- a/tests/compiler/abi.untouched.wat +++ b/tests/compiler/abi.untouched.wat @@ -88,6 +88,8 @@ i32.const 24 i32.shr_s i32.const 24 + i32.const 7 + i32.and i32.shr_s local.set $0 else diff --git a/tests/compiler/retain-i32.ts b/tests/compiler/retain-i32.ts index 5484c06c1b..4065eb74da 100644 --- a/tests/compiler/retain-i32.ts +++ b/tests/compiler/retain-i32.ts @@ -7,7 +7,7 @@ function test(a: u32, b: u32): void { assert((a & b) == (a & b)); assert((a | b) == (a | b)); assert((a ^ b) == (a ^ b)); - assert((a << b) == (a << b)); + assert((a << (b & 7)) == (a << b)); // unsigned assert((a + b) == (a + b)); @@ -16,7 +16,7 @@ function test(a: u32, b: u32): void { assert((a & b) == (a & b)); assert((a | b) == (a | b)); assert((a ^ b) == (a ^ b)); - assert((a << b) == (a << b)); + assert((a << (b & 7)) == (a << b)); } // signed diff --git a/tests/compiler/retain-i32.untouched.wat b/tests/compiler/retain-i32.untouched.wat index a096fb55d4..215c53523c 100644 --- a/tests/compiler/retain-i32.untouched.wat +++ b/tests/compiler/retain-i32.untouched.wat @@ -167,6 +167,8 @@ end local.get $0 local.get $1 + i32.const 7 + i32.and i32.shl i32.const 24 i32.shl @@ -174,6 +176,8 @@ i32.shr_s local.get $0 local.get $1 + i32.const 7 + i32.and i32.shl i32.const 24 i32.shl @@ -311,11 +315,15 @@ end local.get $0 local.get $1 + i32.const 7 + i32.and i32.shl i32.const 255 i32.and local.get $0 local.get $1 + i32.const 7 + i32.and i32.shl i32.const 255 i32.and diff --git a/tests/compiler/std/dataview.untouched.wat b/tests/compiler/std/dataview.untouched.wat index cf9f905ef2..c7acb9845a 100644 --- a/tests/compiler/std/dataview.untouched.wat +++ b/tests/compiler/std/dataview.untouched.wat @@ -2124,6 +2124,8 @@ drop local.get $0 i32.const 8 + i32.const 15 + i32.and i32.shl local.get $0 i32.const 16 @@ -2131,6 +2133,8 @@ i32.const 16 i32.shr_s i32.const 8 + i32.const 15 + i32.and i32.shr_s i32.const 255 i32.and @@ -2344,11 +2348,15 @@ drop local.get $0 i32.const 8 + i32.const 15 + i32.and i32.shl local.get $0 i32.const 65535 i32.and i32.const 8 + i32.const 15 + i32.and i32.shr_u i32.const 255 i32.and diff --git a/tests/compiler/std/polyfills.untouched.wat b/tests/compiler/std/polyfills.untouched.wat index 966b7ef0aa..efe857cedb 100644 --- a/tests/compiler/std/polyfills.untouched.wat +++ b/tests/compiler/std/polyfills.untouched.wat @@ -54,11 +54,15 @@ drop local.get $0 i32.const 8 + i32.const 15 + i32.and i32.shl local.get $0 i32.const 65535 i32.and i32.const 8 + i32.const 15 + i32.and i32.shr_u i32.const 255 i32.and @@ -74,6 +78,8 @@ drop local.get $0 i32.const 8 + i32.const 15 + i32.and i32.shl local.get $0 i32.const 16 @@ -81,6 +87,8 @@ i32.const 16 i32.shr_s i32.const 8 + i32.const 15 + i32.and i32.shr_s i32.const 255 i32.and @@ -347,11 +355,15 @@ drop local.get $0 i32.const 8 + i32.const 15 + i32.and i32.shl local.get $0 i32.const 65535 i32.and i32.const 8 + i32.const 15 + i32.and i32.shr_u i32.const 255 i32.and @@ -374,6 +386,8 @@ drop local.get $0 i32.const 8 + i32.const 15 + i32.and i32.shl local.get $0 i32.const 16 @@ -381,6 +395,8 @@ i32.const 16 i32.shr_s i32.const 8 + i32.const 15 + i32.and i32.shr_s i32.const 255 i32.and From f2d478698857bb4c2f6f045b426de6f627f5a6c4 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Mon, 19 Oct 2020 18:30:39 +0300 Subject: [PATCH 2/5] comments --- src/compiler.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index 9c965446fe..9bd3e084cc 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -5686,7 +5686,7 @@ export class Compiler extends DiagnosticEmitter { switch (type.kind) { case TypeKind.I8: case TypeKind.I16: { - // leftExpr >> (rightExpr & (7 | 15)) + // leftExpr >> (rightExpr & (7|15)) return module.binary( BinaryOp.ShrI32, this.ensureSmallIntegerWrap(leftExpr, type), @@ -5714,7 +5714,7 @@ export class Compiler extends DiagnosticEmitter { } case TypeKind.U8: case TypeKind.U16: { - // leftExpr >>> (rightExpr & (7 | 15)) + // leftExpr >>> (rightExpr & (7|15)) return module.binary( BinaryOp.ShrU32, this.ensureSmallIntegerWrap(leftExpr, type), @@ -5753,7 +5753,7 @@ export class Compiler extends DiagnosticEmitter { case TypeKind.I16: case TypeKind.U8: case TypeKind.U16: { - // leftExpr >>> (rightExpr & (7 | 15)) + // leftExpr >>> (rightExpr & (7|15)) return module.binary( BinaryOp.ShrU32, this.ensureSmallIntegerWrap(leftExpr, type), From 96f74efc2fc9f769b6f07b6ee5f632feefd480f3 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Mon, 19 Oct 2020 18:49:25 +0300 Subject: [PATCH 3/5] skip wrapping LHS for booleans --- src/compiler.ts | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index 9bd3e084cc..ab46db97ac 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -5641,10 +5641,7 @@ export class Compiler extends DiagnosticEmitter { // Cares about garbage bits on the RHS, but only for types smaller than 5 bits var module = this.module; switch (type.kind) { - case TypeKind.BOOL: { - rightExpr = this.ensureSmallIntegerWrap(rightExpr, type); - // falls through - } + case TypeKind.BOOL: case TypeKind.I8: case TypeKind.I16: case TypeKind.U8: @@ -5693,6 +5690,16 @@ export class Compiler extends DiagnosticEmitter { module.binary(BinaryOp.AndI32, rightExpr, module.i32(type.size - 1)) ); } + case TypeKind.BOOL: + case TypeKind.U8: + case TypeKind.U16: { + // leftExpr >>> (rightExpr & (7|15)) + return module.binary( + BinaryOp.ShrU32, + this.ensureSmallIntegerWrap(leftExpr, type), + module.binary(BinaryOp.AndI32, rightExpr, module.i32(type.size - 1)) + ); + } case TypeKind.I32: { return module.binary(BinaryOp.ShrI32, leftExpr, rightExpr); } @@ -5708,19 +5715,6 @@ export class Compiler extends DiagnosticEmitter { rightExpr ); } - case TypeKind.BOOL: { - rightExpr = this.ensureSmallIntegerWrap(rightExpr, type); - // falls through - } - case TypeKind.U8: - case TypeKind.U16: { - // leftExpr >>> (rightExpr & (7|15)) - return module.binary( - BinaryOp.ShrU32, - this.ensureSmallIntegerWrap(leftExpr, type), - module.binary(BinaryOp.AndI32, rightExpr, module.i32(type.size - 1)) - ); - } case TypeKind.U32: { return module.binary(BinaryOp.ShrU32, leftExpr, rightExpr); } @@ -5745,10 +5739,7 @@ export class Compiler extends DiagnosticEmitter { // Cares about garbage bits on the LHS, but on the RHS only for types smaller than 5 bits var module = this.module; switch (type.kind) { - case TypeKind.BOOL: { - rightExpr = this.ensureSmallIntegerWrap(rightExpr, type); - // falls through - } + case TypeKind.BOOL: case TypeKind.I8: case TypeKind.I16: case TypeKind.U8: From e5f071baab85165c393766b1fcf69850d08369d9 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Mon, 19 Oct 2020 18:50:22 +0300 Subject: [PATCH 4/5] new comments --- src/compiler.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index ab46db97ac..dac1a5d9e0 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -5646,7 +5646,7 @@ export class Compiler extends DiagnosticEmitter { case TypeKind.I16: case TypeKind.U8: case TypeKind.U16: { - // leftExpr << (rightExpr & (7|15)) + // leftExpr << (rightExpr & (1|7|15)) return module.binary( BinaryOp.ShlI32, leftExpr, @@ -5693,7 +5693,7 @@ export class Compiler extends DiagnosticEmitter { case TypeKind.BOOL: case TypeKind.U8: case TypeKind.U16: { - // leftExpr >>> (rightExpr & (7|15)) + // leftExpr >>> (rightExpr & (1|7|15)) return module.binary( BinaryOp.ShrU32, this.ensureSmallIntegerWrap(leftExpr, type), @@ -5744,7 +5744,7 @@ export class Compiler extends DiagnosticEmitter { case TypeKind.I16: case TypeKind.U8: case TypeKind.U16: { - // leftExpr >>> (rightExpr & (7|15)) + // leftExpr >>> (rightExpr & (1|7|15)) return module.binary( BinaryOp.ShrU32, this.ensureSmallIntegerWrap(leftExpr, type), From d65284716b2b52679bc3a57ef4b48649f0152453 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Mon, 19 Oct 2020 18:55:33 +0300 Subject: [PATCH 5/5] for boolean simply return LHS --- src/compiler.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index dac1a5d9e0..c8559eeba1 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -5641,12 +5641,12 @@ export class Compiler extends DiagnosticEmitter { // Cares about garbage bits on the RHS, but only for types smaller than 5 bits var module = this.module; switch (type.kind) { - case TypeKind.BOOL: + case TypeKind.BOOL: return leftExpr; case TypeKind.I8: case TypeKind.I16: case TypeKind.U8: case TypeKind.U16: { - // leftExpr << (rightExpr & (1|7|15)) + // leftExpr << (rightExpr & (7|15)) return module.binary( BinaryOp.ShlI32, leftExpr, @@ -5681,6 +5681,7 @@ export class Compiler extends DiagnosticEmitter { // and signedness var module = this.module; switch (type.kind) { + case TypeKind.BOOL: return leftExpr; case TypeKind.I8: case TypeKind.I16: { // leftExpr >> (rightExpr & (7|15)) @@ -5690,10 +5691,9 @@ export class Compiler extends DiagnosticEmitter { module.binary(BinaryOp.AndI32, rightExpr, module.i32(type.size - 1)) ); } - case TypeKind.BOOL: case TypeKind.U8: case TypeKind.U16: { - // leftExpr >>> (rightExpr & (1|7|15)) + // leftExpr >>> (rightExpr & (7|15)) return module.binary( BinaryOp.ShrU32, this.ensureSmallIntegerWrap(leftExpr, type), @@ -5739,12 +5739,12 @@ export class Compiler extends DiagnosticEmitter { // Cares about garbage bits on the LHS, but on the RHS only for types smaller than 5 bits var module = this.module; switch (type.kind) { - case TypeKind.BOOL: + case TypeKind.BOOL: return leftExpr; case TypeKind.I8: case TypeKind.I16: case TypeKind.U8: case TypeKind.U16: { - // leftExpr >>> (rightExpr & (1|7|15)) + // leftExpr >>> (rightExpr & (7|15)) return module.binary( BinaryOp.ShrU32, this.ensureSmallIntegerWrap(leftExpr, type),