From a0fcfd785b0bdbde7c515e8cc63759ce73d12631 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Fri, 30 Oct 2020 00:53:17 +0200 Subject: [PATCH 1/6] init --- src/compiler.ts | 36 ++ tests/compiler/resolve-binary.optimized.wat | 34 +- tests/compiler/resolve-binary.untouched.wat | 217 +------ tests/compiler/std/math.optimized.wat | 432 -------------- tests/compiler/std/math.untouched.wat | 622 ++------------------ 5 files changed, 90 insertions(+), 1251 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index 784324e2aa..749ed557ca 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -5351,6 +5351,17 @@ export class Compiler extends DiagnosticEmitter { } case TypeKind.I32: case TypeKind.U32: { + if ( + getExpressionId(leftExpr) == ExpressionId.Const && + getExpressionId(rightExpr) == ExpressionId.Const + ) { + let leftValue = getConstValueI32(leftExpr); + let rightValue = getConstValueI32(rightExpr); + return module.i32(i64_low(i64_pow( + i64_new(leftValue), + i64_new(rightValue) + ))); + } let instance = this.i32PowInstance; if (!instance) { let prototype = this.program.lookupGlobal(CommonNames.ipow32); @@ -5377,6 +5388,15 @@ export class Compiler extends DiagnosticEmitter { } case TypeKind.I64: case TypeKind.U64: { + if ( + getExpressionId(leftExpr) == ExpressionId.Const && + getExpressionId(rightExpr) == ExpressionId.Const + ) { + let leftValue = i64_new(getConstValueI64Low(leftExpr), getConstValueI64High(leftExpr)); + let rightValue = i64_new(getConstValueI64Low(rightExpr), getConstValueI64High(rightExpr)); + let result = i64_pow(leftValue, rightValue); + return module.i64(i64_low(result), i64_high(result)); + } let instance = this.i64PowInstance; if (!instance) { let prototype = this.program.lookupGlobal(CommonNames.ipow64); @@ -5422,6 +5442,14 @@ export class Compiler extends DiagnosticEmitter { return this.makeCallDirect(instance, [ leftExpr, rightExpr ], reportNode); } case TypeKind.F32: { + if ( + getExpressionId(leftExpr) == ExpressionId.Const && + getExpressionId(rightExpr) == ExpressionId.Const + ) { + let leftValue = getConstValueF32(leftExpr); + let rightValue = getConstValueF32(rightExpr); + return module.f32(Math.fround(Math.pow(leftValue, rightValue))); + } let instance = this.f32PowInstance; if (!instance) { let namespace = this.program.lookupGlobal(CommonNames.Mathf); @@ -5451,6 +5479,14 @@ export class Compiler extends DiagnosticEmitter { } // Math.pow otherwise (result is f64) case TypeKind.F64: { + if ( + getExpressionId(leftExpr) == ExpressionId.Const && + getExpressionId(rightExpr) == ExpressionId.Const + ) { + let leftValue = getConstValueF64(leftExpr); + let rightValue = getConstValueF64(rightExpr); + return module.f64(Math.pow(leftValue, rightValue)); + } let instance = this.f64PowInstance; if (!instance) { let namespace = this.program.lookupGlobal(CommonNames.Math); diff --git a/tests/compiler/resolve-binary.optimized.wat b/tests/compiler/resolve-binary.optimized.wat index 3466deb879..9e71a1544e 100644 --- a/tests/compiler/resolve-binary.optimized.wat +++ b/tests/compiler/resolve-binary.optimized.wat @@ -1296,9 +1296,6 @@ local.get $1 ) (func $start:resolve-binary - (local $0 i32) - (local $1 i32) - (local $2 i32) i32.const 1056 i32.const 1056 call $~lib/string/String.__eq @@ -1676,36 +1673,7 @@ call $~lib/builtins/abort unreachable end - i32.const 2 - local.set $0 - i32.const 2 - local.set $1 - i32.const 1 - local.set $2 - loop $while-continue|0 - local.get $1 - if - local.get $0 - local.get $2 - i32.mul - local.get $2 - local.get $1 - i32.const 1 - i32.and - select - local.set $2 - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - br $while-continue|0 - end - end - local.get $2 + i32.const 4 call $~lib/number/I32#toString i32.const 2752 call $~lib/string/String.__eq diff --git a/tests/compiler/resolve-binary.untouched.wat b/tests/compiler/resolve-binary.untouched.wat index 8724d81b6c..2a71bb0895 100644 --- a/tests/compiler/resolve-binary.untouched.wat +++ b/tests/compiler/resolve-binary.untouched.wat @@ -4533,211 +4533,6 @@ local.get $0 call $~lib/util/number/dtoa ) - (func $~lib/math/ipow32 (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - i32.const 1 - local.set $2 - i32.const 0 - i32.const 1 - i32.lt_s - drop - local.get $1 - i32.const 0 - i32.le_s - if - local.get $0 - i32.const -1 - i32.eq - if - i32.const -1 - i32.const 1 - local.get $1 - i32.const 1 - i32.and - select - return - end - local.get $1 - i32.const 0 - i32.eq - local.get $0 - i32.const 1 - i32.eq - i32.or - return - else - local.get $1 - i32.const 1 - i32.eq - if - local.get $0 - return - else - local.get $1 - i32.const 2 - i32.eq - if - local.get $0 - local.get $0 - i32.mul - return - else - local.get $1 - i32.const 32 - i32.lt_s - if - i32.const 32 - local.get $1 - i32.clz - i32.sub - local.set $3 - block $break|0 - block $case4|0 - block $case3|0 - block $case2|0 - block $case1|0 - block $case0|0 - local.get $3 - local.set $4 - local.get $4 - i32.const 5 - i32.eq - br_if $case0|0 - local.get $4 - i32.const 4 - i32.eq - br_if $case1|0 - local.get $4 - i32.const 3 - i32.eq - br_if $case2|0 - local.get $4 - i32.const 2 - i32.eq - br_if $case3|0 - local.get $4 - i32.const 1 - i32.eq - br_if $case4|0 - br $break|0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - end - local.get $2 - return - end - end - end - end - loop $while-continue|1 - local.get $1 - local.set $3 - local.get $3 - if - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - br $while-continue|1 - end - end - local.get $2 - ) (func $resolve-binary/Foo#constructor (param $0 i32) (result i32) local.get $0 i32.eqz @@ -5464,9 +5259,7 @@ call $~lib/builtins/abort unreachable end - i32.const 2 - i32.const 2 - call $~lib/math/ipow32 + i32.const 4 i32.const 10 call $~lib/number/I32#toString local.tee $26 @@ -5481,9 +5274,7 @@ call $~lib/builtins/abort unreachable end - f64.const 2 - f64.const 2 - call $~lib/math/NativeMath.pow + f64.const 4 i32.const 0 call $~lib/number/F64#toString local.tee $27 @@ -5498,9 +5289,7 @@ call $~lib/builtins/abort unreachable end - f64.const 2 - f64.const 2 - call $~lib/math/NativeMath.pow + f64.const 4 i32.const 0 call $~lib/number/F64#toString local.tee $28 diff --git a/tests/compiler/std/math.optimized.wat b/tests/compiler/std/math.optimized.wat index b3418d80b0..7fa6188aab 100644 --- a/tests/compiler/std/math.optimized.wat +++ b/tests/compiler/std/math.optimized.wat @@ -15,7 +15,6 @@ (type $i64_i64_i64_i64_i64_=>_none (func (param i64 i64 i64 i64 i64))) (type $f64_=>_none (func (param f64))) (type $i32_=>_i32 (func (param i32) (result i32))) - (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i64_=>_i32 (func (param i64) (result i32))) (type $f64_=>_i32 (func (param f64) (result i32))) (type $i64_=>_i64 (func (param i64) (result i64))) @@ -10838,35 +10837,6 @@ end local.get $2 ) - (func $~lib/math/ipow32 (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - i32.const 1 - local.set $2 - loop $while-continue|0 - local.get $1 - if - local.get $0 - local.get $2 - i32.mul - local.get $2 - local.get $1 - i32.const 1 - i32.and - select - local.set $2 - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - br $while-continue|0 - end - end - local.get $2 - ) (func $start:std/math (local $0 f64) (local $1 i32) @@ -49406,382 +49376,6 @@ call $~lib/builtins/abort unreachable end - i32.const 1 - i32.const 3 - call $~lib/math/ipow32 - i32.const 1 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 4082 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const -2 - i32.const 3 - call $~lib/math/ipow32 - i32.const -8 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 4083 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const -1 - i32.const 0 - call $~lib/math/ipow32 - i32.const 1 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 4084 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const -1 - i32.const -1 - call $~lib/math/ipow32 - i32.const -1 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 4085 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const -1 - i32.const -2 - call $~lib/math/ipow32 - i32.const 1 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 4086 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const -1 - i32.const -3 - call $~lib/math/ipow32 - i32.const -1 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 4087 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 0 - i32.const -2 - call $~lib/math/ipow32 - if - i32.const 0 - i32.const 1056 - i32.const 4089 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 0 - i32.const -1 - call $~lib/math/ipow32 - if - i32.const 0 - i32.const 1056 - i32.const 4090 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 0 - i32.const 2 - call $~lib/math/ipow32 - if - i32.const 0 - i32.const 1056 - i32.const 4093 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 1 - i32.const -2 - call $~lib/math/ipow32 - i32.const 1 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 4095 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 1 - i32.const -1 - call $~lib/math/ipow32 - i32.const 1 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 4096 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 1 - i32.const 2 - call $~lib/math/ipow32 - i32.const 1 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 4099 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 1 - i32.const 3 - call $~lib/math/ipow32 - i32.const 255 - i32.and - i32.const 1 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 4101 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const -2 - i32.const 3 - call $~lib/math/ipow32 - i32.const 255 - i32.and - i32.const 248 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 4102 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 4 - i32.const 7 - call $~lib/math/ipow32 - i32.const 65535 - i32.and - i32.const 16384 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 4103 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 4 - i32.const 8 - call $~lib/math/ipow32 - i32.const 65535 - i32.and - if - i32.const 0 - i32.const 1056 - i32.const 4104 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 5 - i32.const 10 - call $~lib/math/ipow32 - i32.const 65535 - i32.and - i32.const 761 - i32.ne - if - i32.const 0 - i32.const 1056 - i32.const 4105 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 0 - i64.const 0 - call $~lib/math/ipow64 - i64.const 1 - i64.ne - if - i32.const 0 - i32.const 1056 - i32.const 4107 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 0 - i64.const 1 - call $~lib/math/ipow64 - i64.eqz - i32.eqz - if - i32.const 0 - i32.const 1056 - i32.const 4108 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 1 - i64.const 3 - call $~lib/math/ipow64 - i64.const 1 - i64.ne - if - i32.const 0 - i32.const 1056 - i32.const 4109 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 2 - i64.const 3 - call $~lib/math/ipow64 - i64.const 8 - i64.ne - if - i32.const 0 - i32.const 1056 - i32.const 4110 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 4294967295 - i64.const 3 - call $~lib/math/ipow64 - i64.const 12884901887 - i64.ne - if - i32.const 0 - i32.const 1056 - i32.const 4111 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 65535 - i64.const 3 - call $~lib/math/ipow64 - i64.const 281462092005375 - i64.ne - if - i32.const 0 - i32.const 1056 - i32.const 4112 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 65535 - i64.const 8 - call $~lib/math/ipow64 - i64.const -15762478437236735 - i64.ne - if - i32.const 0 - i32.const 1056 - i32.const 4113 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 61731 - i64.const 4 - call $~lib/math/ipow64 - i64.const -3925184889716469295 - i64.ne - if - i32.const 0 - i32.const 1056 - i32.const 4114 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 61731 - i64.const 4 - call $~lib/math/ipow64 - i64.const -3925184889716469295 - i64.ne - if - i32.const 0 - i32.const 1056 - i32.const 4115 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 57055 - i64.const 3 - call $~lib/math/ipow64 - i64.const 339590 - i64.const 3 - call $~lib/math/ipow64 - i64.add - i64.const 340126 - i64.const 3 - call $~lib/math/ipow64 - i64.eq - if - i32.const 0 - i32.const 1056 - i32.const 4117 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 57055 - i64.const 3 - call $~lib/math/ipow64 - i64.const 339590 - i64.const 3 - call $~lib/math/ipow64 - i64.add - i64.const 39347712995520375 - i64.ne - if - i32.const 0 - i32.const 1056 - i32.const 4118 - i32.const 1 - call $~lib/builtins/abort - unreachable - end f64.const 1 f64.const 0.5 call $~lib/math/NativeMath.pow @@ -49821,32 +49415,6 @@ call $~lib/builtins/abort unreachable end - f64.const 0 - f64.const 0 - call $~lib/math/NativeMath.pow - f64.const 1 - f64.ne - if - i32.const 0 - i32.const 1056 - i32.const 4123 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - f64.const 1 - f64.const 1 - call $~lib/math/NativeMath.pow - f64.const 1 - f64.ne - if - i32.const 0 - i32.const 1056 - i32.const 4124 - i32.const 1 - call $~lib/builtins/abort - unreachable - end ) (func $~start call $start:std/math diff --git a/tests/compiler/std/math.untouched.wat b/tests/compiler/std/math.untouched.wat index 271d353465..d62d404dc5 100644 --- a/tests/compiler/std/math.untouched.wat +++ b/tests/compiler/std/math.untouched.wat @@ -14,7 +14,6 @@ (type $i64_=>_none (func (param i64))) (type $f64_=>_none (func (param f64))) (type $i32_=>_i32 (func (param i32) (result i32))) - (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i64_i64_i64_i64_i64_i32_=>_i32 (func (param i64 i64 i64 i64 i64 i32) (result i32))) (type $f32_=>_i32 (func (param f32) (result i32))) (type $f32_i32_f32_f32_i32_=>_i32 (func (param f32 i32 f32 f32 i32) (result i32))) @@ -16213,211 +16212,6 @@ end local.get $2 ) - (func $~lib/math/ipow32 (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - i32.const 1 - local.set $2 - i32.const 0 - i32.const 1 - i32.lt_s - drop - local.get $1 - i32.const 0 - i32.le_s - if - local.get $0 - i32.const -1 - i32.eq - if - i32.const -1 - i32.const 1 - local.get $1 - i32.const 1 - i32.and - select - return - end - local.get $1 - i32.const 0 - i32.eq - local.get $0 - i32.const 1 - i32.eq - i32.or - return - else - local.get $1 - i32.const 1 - i32.eq - if - local.get $0 - return - else - local.get $1 - i32.const 2 - i32.eq - if - local.get $0 - local.get $0 - i32.mul - return - else - local.get $1 - i32.const 32 - i32.lt_s - if - i32.const 32 - local.get $1 - i32.clz - i32.sub - local.set $3 - block $break|0 - block $case4|0 - block $case3|0 - block $case2|0 - block $case1|0 - block $case0|0 - local.get $3 - local.set $4 - local.get $4 - i32.const 5 - i32.eq - br_if $case0|0 - local.get $4 - i32.const 4 - i32.eq - br_if $case1|0 - local.get $4 - i32.const 3 - i32.eq - br_if $case2|0 - local.get $4 - i32.const 2 - i32.eq - br_if $case3|0 - local.get $4 - i32.const 1 - i32.eq - br_if $case4|0 - br $break|0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - end - local.get $2 - return - end - end - end - end - loop $while-continue|1 - local.get $1 - local.set $3 - local.get $3 - if - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - br $while-continue|1 - end - end - local.get $2 - ) (func $start:std/math (local $0 f64) (local $1 i32) @@ -58784,117 +58578,37 @@ i32.eq drop i32.const 1 - i32.const 3 - call $~lib/math/ipow32 i32.const 1 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4082 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const -2 - i32.const 3 - call $~lib/math/ipow32 + drop + i32.const -8 i32.const -8 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4083 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const -1 - i32.const 0 - call $~lib/math/ipow32 + drop + i32.const 1 i32.const 1 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4084 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const -1 + drop i32.const -1 - call $~lib/math/ipow32 i32.const -1 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4085 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const -1 - i32.const -2 - call $~lib/math/ipow32 + drop + i32.const 1 i32.const 1 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4086 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i32.const -1 - i32.const -3 - call $~lib/math/ipow32 i32.const -1 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4087 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i32.const 0 - i32.const -2 - call $~lib/math/ipow32 i32.const 0 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4089 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i32.const 0 - i32.const -1 - call $~lib/math/ipow32 i32.const 0 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4090 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i32.const 1 i32.const 0 i32.const 0 @@ -58914,47 +58628,17 @@ i32.eq drop i32.const 0 - i32.const 2 - call $~lib/math/ipow32 i32.const 0 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4093 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i32.const 1 - i32.const -2 - call $~lib/math/ipow32 i32.const 1 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4095 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i32.const 1 - i32.const -1 - call $~lib/math/ipow32 i32.const 1 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4096 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i32.const 1 i32.const 0 i32.const 0 @@ -58974,267 +58658,81 @@ i32.eq drop i32.const 1 - i32.const 2 - call $~lib/math/ipow32 i32.const 1 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4099 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i32.const 1 - i32.const 3 - call $~lib/math/ipow32 - i32.const 24 - i32.shl - i32.const 24 - i32.shr_s i32.const 1 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4101 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const -2 - i32.const 3 - call $~lib/math/ipow32 - i32.const 24 - i32.shl - i32.const 24 - i32.shr_s + drop + i32.const -8 i32.const -8 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4102 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 4 - i32.const 7 - call $~lib/math/ipow32 - i32.const 65535 - i32.and + drop + i32.const 16384 i32.const 16384 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4103 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 4 - i32.const 8 - call $~lib/math/ipow32 + drop + i32.const 65536 i32.const 65535 i32.and i32.const 0 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4104 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 5 - i32.const 10 - call $~lib/math/ipow32 + drop + i32.const 9765625 i32.const 65535 i32.and i32.const 761 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4105 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 0 - i64.const 0 - call $~lib/math/ipow64 + drop + i64.const 1 i64.const 1 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4107 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i64.const 0 - i64.const 1 - call $~lib/math/ipow64 i64.const 0 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4108 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i64.const 1 - i64.const 3 - call $~lib/math/ipow64 i64.const 1 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4109 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 2 - i64.const 3 - call $~lib/math/ipow64 + drop + i64.const 8 i64.const 8 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4110 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 4294967295 - i64.const 3 - call $~lib/math/ipow64 + drop + i64.const 12884901887 i64.const 12884901887 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4111 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 65535 - i64.const 3 - call $~lib/math/ipow64 + drop + i64.const 281462092005375 i64.const 281462092005375 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4112 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 65535 - i64.const 8 - call $~lib/math/ipow64 + drop + i64.const -15762478437236735 i64.const -15762478437236735 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4113 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 61731 - i64.const 4 - call $~lib/math/ipow64 + drop + i64.const -3925184889716469295 i64.const -3925184889716469295 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4114 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 61731 - i64.const 4 - call $~lib/math/ipow64 + drop + i64.const -3925184889716469295 i64.const -3925184889716469295 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4115 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 57055 - i64.const 3 - call $~lib/math/ipow64 - i64.const 339590 - i64.const 3 - call $~lib/math/ipow64 + drop + i64.const 185729602441375 + i64.const 39161983393079000 i64.add - i64.const 340126 - i64.const 3 - call $~lib/math/ipow64 + i64.const 39347712995520376 i64.ne - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4117 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 57055 - i64.const 3 - call $~lib/math/ipow64 - i64.const 339590 - i64.const 3 - call $~lib/math/ipow64 + drop + i64.const 185729602441375 + i64.const 39161983393079000 i64.add i64.const 39347712995520375 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4118 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i32.const 1 f64.convert_i32_u f64.const 0.5 @@ -59280,34 +58778,14 @@ call $~lib/builtins/abort unreachable end - f64.const 0 - f64.const 0 - call $~lib/math/NativeMath.pow f64.const 1 - f64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4123 - i32.const 1 - call $~lib/builtins/abort - unreachable - end f64.const 1 + f64.eq + drop f64.const 1 - call $~lib/math/NativeMath.pow f64.const 1 f64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4124 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop ) (func $~start call $start:std/math From f05f9d060fdbedb6be6764524b47a3447f4dbd11 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Fri, 30 Oct 2020 01:02:05 +0200 Subject: [PATCH 2/6] fix --- src/compiler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler.ts b/src/compiler.ts index 749ed557ca..24453f794c 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -5448,7 +5448,7 @@ export class Compiler extends DiagnosticEmitter { ) { let leftValue = getConstValueF32(leftExpr); let rightValue = getConstValueF32(rightExpr); - return module.f32(Math.fround(Math.pow(leftValue, rightValue))); + return module.f32(f32(Math.pow(leftValue, rightValue))); } let instance = this.f32PowInstance; if (!instance) { From 8a3fd3e3c742cc18b8f1476fbead0a5cdee6e79f Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Fri, 30 Oct 2020 01:08:50 +0200 Subject: [PATCH 3/6] same for usize / isize --- src/compiler.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/compiler.ts b/src/compiler.ts index 24453f794c..37bfa5ca4a 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -5418,6 +5418,24 @@ export class Compiler extends DiagnosticEmitter { case TypeKind.ISIZE: case TypeKind.USIZE: { let isWasm64 = this.options.isWasm64; + if ( + getExpressionId(leftExpr) == ExpressionId.Const && + getExpressionId(rightExpr) == ExpressionId.Const + ) { + if (isWasm64) { + let leftValue = i64_new(getConstValueI64Low(leftExpr), getConstValueI64High(leftExpr)); + let rightValue = i64_new(getConstValueI64Low(rightExpr), getConstValueI64High(rightExpr)); + let result = i64_pow(leftValue, rightValue); + return module.i64(i64_low(result), i64_high(result)); + } else { + let leftValue = getConstValueI32(leftExpr); + let rightValue = getConstValueI32(rightExpr); + return module.i32(i64_low(i64_pow( + i64_new(leftValue), + i64_new(rightValue) + ))); + } + } let instance = isWasm64 ? this.i64PowInstance : this.i32PowInstance; if (!instance) { let prototype = this.program.lookupGlobal(isWasm64 ? CommonNames.ipow64 : CommonNames.ipow32); From 6cf5cfb370add7819192bfedd9895c2c127792e4 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Wed, 4 Nov 2020 01:34:43 +0200 Subject: [PATCH 4/6] don't const fold for -O0 --- src/compiler.ts | 9 + tests/compiler/resolve-binary.untouched.wat | 217 ++++++- tests/compiler/std/math.untouched.wat | 622 ++++++++++++++++++-- 3 files changed, 795 insertions(+), 53 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index 37bfa5ca4a..76915d0db2 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -5333,6 +5333,10 @@ export class Compiler extends DiagnosticEmitter { makePow(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type, reportNode: Node): ExpressionRef { // Cares about garbage bits let module = this.module; + let canOptimize = ( + this.options.optimizeLevelHint != 0 || + this.options.shrinkLevelHint != 0 + ); switch (type.kind) { case TypeKind.BOOL: { return module.select( @@ -5352,6 +5356,7 @@ export class Compiler extends DiagnosticEmitter { case TypeKind.I32: case TypeKind.U32: { if ( + canOptimize && getExpressionId(leftExpr) == ExpressionId.Const && getExpressionId(rightExpr) == ExpressionId.Const ) { @@ -5389,6 +5394,7 @@ export class Compiler extends DiagnosticEmitter { case TypeKind.I64: case TypeKind.U64: { if ( + canOptimize && getExpressionId(leftExpr) == ExpressionId.Const && getExpressionId(rightExpr) == ExpressionId.Const ) { @@ -5419,6 +5425,7 @@ export class Compiler extends DiagnosticEmitter { case TypeKind.USIZE: { let isWasm64 = this.options.isWasm64; if ( + canOptimize && getExpressionId(leftExpr) == ExpressionId.Const && getExpressionId(rightExpr) == ExpressionId.Const ) { @@ -5461,6 +5468,7 @@ export class Compiler extends DiagnosticEmitter { } case TypeKind.F32: { if ( + canOptimize && getExpressionId(leftExpr) == ExpressionId.Const && getExpressionId(rightExpr) == ExpressionId.Const ) { @@ -5498,6 +5506,7 @@ export class Compiler extends DiagnosticEmitter { // Math.pow otherwise (result is f64) case TypeKind.F64: { if ( + canOptimize && getExpressionId(leftExpr) == ExpressionId.Const && getExpressionId(rightExpr) == ExpressionId.Const ) { diff --git a/tests/compiler/resolve-binary.untouched.wat b/tests/compiler/resolve-binary.untouched.wat index 2a71bb0895..8724d81b6c 100644 --- a/tests/compiler/resolve-binary.untouched.wat +++ b/tests/compiler/resolve-binary.untouched.wat @@ -4533,6 +4533,211 @@ local.get $0 call $~lib/util/number/dtoa ) + (func $~lib/math/ipow32 (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + i32.const 1 + local.set $2 + i32.const 0 + i32.const 1 + i32.lt_s + drop + local.get $1 + i32.const 0 + i32.le_s + if + local.get $0 + i32.const -1 + i32.eq + if + i32.const -1 + i32.const 1 + local.get $1 + i32.const 1 + i32.and + select + return + end + local.get $1 + i32.const 0 + i32.eq + local.get $0 + i32.const 1 + i32.eq + i32.or + return + else + local.get $1 + i32.const 1 + i32.eq + if + local.get $0 + return + else + local.get $1 + i32.const 2 + i32.eq + if + local.get $0 + local.get $0 + i32.mul + return + else + local.get $1 + i32.const 32 + i32.lt_s + if + i32.const 32 + local.get $1 + i32.clz + i32.sub + local.set $3 + block $break|0 + block $case4|0 + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + local.get $3 + local.set $4 + local.get $4 + i32.const 5 + i32.eq + br_if $case0|0 + local.get $4 + i32.const 4 + i32.eq + br_if $case1|0 + local.get $4 + i32.const 3 + i32.eq + br_if $case2|0 + local.get $4 + i32.const 2 + i32.eq + br_if $case3|0 + local.get $4 + i32.const 1 + i32.eq + br_if $case4|0 + br $break|0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + end + local.get $2 + return + end + end + end + end + loop $while-continue|1 + local.get $1 + local.set $3 + local.get $3 + if + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + br $while-continue|1 + end + end + local.get $2 + ) (func $resolve-binary/Foo#constructor (param $0 i32) (result i32) local.get $0 i32.eqz @@ -5259,7 +5464,9 @@ call $~lib/builtins/abort unreachable end - i32.const 4 + i32.const 2 + i32.const 2 + call $~lib/math/ipow32 i32.const 10 call $~lib/number/I32#toString local.tee $26 @@ -5274,7 +5481,9 @@ call $~lib/builtins/abort unreachable end - f64.const 4 + f64.const 2 + f64.const 2 + call $~lib/math/NativeMath.pow i32.const 0 call $~lib/number/F64#toString local.tee $27 @@ -5289,7 +5498,9 @@ call $~lib/builtins/abort unreachable end - f64.const 4 + f64.const 2 + f64.const 2 + call $~lib/math/NativeMath.pow i32.const 0 call $~lib/number/F64#toString local.tee $28 diff --git a/tests/compiler/std/math.untouched.wat b/tests/compiler/std/math.untouched.wat index d62d404dc5..271d353465 100644 --- a/tests/compiler/std/math.untouched.wat +++ b/tests/compiler/std/math.untouched.wat @@ -14,6 +14,7 @@ (type $i64_=>_none (func (param i64))) (type $f64_=>_none (func (param f64))) (type $i32_=>_i32 (func (param i32) (result i32))) + (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i64_i64_i64_i64_i64_i32_=>_i32 (func (param i64 i64 i64 i64 i64 i32) (result i32))) (type $f32_=>_i32 (func (param f32) (result i32))) (type $f32_i32_f32_f32_i32_=>_i32 (func (param f32 i32 f32 f32 i32) (result i32))) @@ -16212,6 +16213,211 @@ end local.get $2 ) + (func $~lib/math/ipow32 (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + i32.const 1 + local.set $2 + i32.const 0 + i32.const 1 + i32.lt_s + drop + local.get $1 + i32.const 0 + i32.le_s + if + local.get $0 + i32.const -1 + i32.eq + if + i32.const -1 + i32.const 1 + local.get $1 + i32.const 1 + i32.and + select + return + end + local.get $1 + i32.const 0 + i32.eq + local.get $0 + i32.const 1 + i32.eq + i32.or + return + else + local.get $1 + i32.const 1 + i32.eq + if + local.get $0 + return + else + local.get $1 + i32.const 2 + i32.eq + if + local.get $0 + local.get $0 + i32.mul + return + else + local.get $1 + i32.const 32 + i32.lt_s + if + i32.const 32 + local.get $1 + i32.clz + i32.sub + local.set $3 + block $break|0 + block $case4|0 + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + local.get $3 + local.set $4 + local.get $4 + i32.const 5 + i32.eq + br_if $case0|0 + local.get $4 + i32.const 4 + i32.eq + br_if $case1|0 + local.get $4 + i32.const 3 + i32.eq + br_if $case2|0 + local.get $4 + i32.const 2 + i32.eq + br_if $case3|0 + local.get $4 + i32.const 1 + i32.eq + br_if $case4|0 + br $break|0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + end + local.get $2 + return + end + end + end + end + loop $while-continue|1 + local.get $1 + local.set $3 + local.get $3 + if + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + br $while-continue|1 + end + end + local.get $2 + ) (func $start:std/math (local $0 f64) (local $1 i32) @@ -58578,37 +58784,117 @@ i32.eq drop i32.const 1 + i32.const 3 + call $~lib/math/ipow32 i32.const 1 i32.eq - drop - i32.const -8 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4082 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const -2 + i32.const 3 + call $~lib/math/ipow32 i32.const -8 i32.eq - drop - i32.const 1 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4083 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const -1 + i32.const 0 + call $~lib/math/ipow32 i32.const 1 i32.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4084 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i32.const -1 i32.const -1 + call $~lib/math/ipow32 + i32.const -1 i32.eq - drop - i32.const 1 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4085 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const -1 + i32.const -2 + call $~lib/math/ipow32 i32.const 1 i32.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4086 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i32.const -1 + i32.const -3 + call $~lib/math/ipow32 i32.const -1 i32.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4087 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i32.const 0 + i32.const -2 + call $~lib/math/ipow32 i32.const 0 i32.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4089 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i32.const 0 + i32.const -1 + call $~lib/math/ipow32 i32.const 0 i32.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4090 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i32.const 1 i32.const 0 i32.const 0 @@ -58628,17 +58914,47 @@ i32.eq drop i32.const 0 + i32.const 2 + call $~lib/math/ipow32 i32.const 0 i32.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4093 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i32.const 1 + i32.const -2 + call $~lib/math/ipow32 i32.const 1 i32.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4095 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i32.const 1 + i32.const -1 + call $~lib/math/ipow32 i32.const 1 i32.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4096 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i32.const 1 i32.const 0 i32.const 0 @@ -58658,81 +58974,267 @@ i32.eq drop i32.const 1 + i32.const 2 + call $~lib/math/ipow32 i32.const 1 i32.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4099 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i32.const 1 + i32.const 3 + call $~lib/math/ipow32 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s i32.const 1 i32.eq - drop - i32.const -8 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4101 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const -2 + i32.const 3 + call $~lib/math/ipow32 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s i32.const -8 i32.eq - drop - i32.const 16384 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4102 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 4 + i32.const 7 + call $~lib/math/ipow32 + i32.const 65535 + i32.and i32.const 16384 i32.eq - drop - i32.const 65536 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4103 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 4 + i32.const 8 + call $~lib/math/ipow32 i32.const 65535 i32.and i32.const 0 i32.eq - drop - i32.const 9765625 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4104 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 5 + i32.const 10 + call $~lib/math/ipow32 i32.const 65535 i32.and i32.const 761 i32.eq - drop - i64.const 1 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4105 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 0 + i64.const 0 + call $~lib/math/ipow64 i64.const 1 i64.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4107 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i64.const 0 + i64.const 1 + call $~lib/math/ipow64 i64.const 0 i64.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4108 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i64.const 1 + i64.const 3 + call $~lib/math/ipow64 i64.const 1 i64.eq - drop - i64.const 8 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4109 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 2 + i64.const 3 + call $~lib/math/ipow64 i64.const 8 i64.eq - drop - i64.const 12884901887 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4110 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 4294967295 + i64.const 3 + call $~lib/math/ipow64 i64.const 12884901887 i64.eq - drop - i64.const 281462092005375 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4111 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 65535 + i64.const 3 + call $~lib/math/ipow64 i64.const 281462092005375 i64.eq - drop - i64.const -15762478437236735 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4112 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 65535 + i64.const 8 + call $~lib/math/ipow64 i64.const -15762478437236735 i64.eq - drop - i64.const -3925184889716469295 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4113 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 61731 + i64.const 4 + call $~lib/math/ipow64 i64.const -3925184889716469295 i64.eq - drop - i64.const -3925184889716469295 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4114 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 61731 + i64.const 4 + call $~lib/math/ipow64 i64.const -3925184889716469295 i64.eq - drop - i64.const 185729602441375 - i64.const 39161983393079000 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4115 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 57055 + i64.const 3 + call $~lib/math/ipow64 + i64.const 339590 + i64.const 3 + call $~lib/math/ipow64 i64.add - i64.const 39347712995520376 + i64.const 340126 + i64.const 3 + call $~lib/math/ipow64 i64.ne - drop - i64.const 185729602441375 - i64.const 39161983393079000 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4117 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 57055 + i64.const 3 + call $~lib/math/ipow64 + i64.const 339590 + i64.const 3 + call $~lib/math/ipow64 i64.add i64.const 39347712995520375 i64.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4118 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i32.const 1 f64.convert_i32_u f64.const 0.5 @@ -58778,14 +59280,34 @@ call $~lib/builtins/abort unreachable end - f64.const 1 + f64.const 0 + f64.const 0 + call $~lib/math/NativeMath.pow f64.const 1 f64.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4123 + i32.const 1 + call $~lib/builtins/abort + unreachable + end f64.const 1 f64.const 1 + call $~lib/math/NativeMath.pow + f64.const 1 f64.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4124 + i32.const 1 + call $~lib/builtins/abort + unreachable + end ) (func $~start call $start:std/math From 79a6bc471ab824e742798f4986303856f031c316 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Wed, 4 Nov 2020 01:34:43 +0200 Subject: [PATCH 5/6] Revert "don't const fold for -O0" This reverts commit 6cf5cfb370add7819192bfedd9895c2c127792e4. --- src/compiler.ts | 9 - tests/compiler/resolve-binary.untouched.wat | 217 +------ tests/compiler/std/math.untouched.wat | 622 ++------------------ 3 files changed, 53 insertions(+), 795 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index 76915d0db2..37bfa5ca4a 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -5333,10 +5333,6 @@ export class Compiler extends DiagnosticEmitter { makePow(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type, reportNode: Node): ExpressionRef { // Cares about garbage bits let module = this.module; - let canOptimize = ( - this.options.optimizeLevelHint != 0 || - this.options.shrinkLevelHint != 0 - ); switch (type.kind) { case TypeKind.BOOL: { return module.select( @@ -5356,7 +5352,6 @@ export class Compiler extends DiagnosticEmitter { case TypeKind.I32: case TypeKind.U32: { if ( - canOptimize && getExpressionId(leftExpr) == ExpressionId.Const && getExpressionId(rightExpr) == ExpressionId.Const ) { @@ -5394,7 +5389,6 @@ export class Compiler extends DiagnosticEmitter { case TypeKind.I64: case TypeKind.U64: { if ( - canOptimize && getExpressionId(leftExpr) == ExpressionId.Const && getExpressionId(rightExpr) == ExpressionId.Const ) { @@ -5425,7 +5419,6 @@ export class Compiler extends DiagnosticEmitter { case TypeKind.USIZE: { let isWasm64 = this.options.isWasm64; if ( - canOptimize && getExpressionId(leftExpr) == ExpressionId.Const && getExpressionId(rightExpr) == ExpressionId.Const ) { @@ -5468,7 +5461,6 @@ export class Compiler extends DiagnosticEmitter { } case TypeKind.F32: { if ( - canOptimize && getExpressionId(leftExpr) == ExpressionId.Const && getExpressionId(rightExpr) == ExpressionId.Const ) { @@ -5506,7 +5498,6 @@ export class Compiler extends DiagnosticEmitter { // Math.pow otherwise (result is f64) case TypeKind.F64: { if ( - canOptimize && getExpressionId(leftExpr) == ExpressionId.Const && getExpressionId(rightExpr) == ExpressionId.Const ) { diff --git a/tests/compiler/resolve-binary.untouched.wat b/tests/compiler/resolve-binary.untouched.wat index 8724d81b6c..2a71bb0895 100644 --- a/tests/compiler/resolve-binary.untouched.wat +++ b/tests/compiler/resolve-binary.untouched.wat @@ -4533,211 +4533,6 @@ local.get $0 call $~lib/util/number/dtoa ) - (func $~lib/math/ipow32 (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - i32.const 1 - local.set $2 - i32.const 0 - i32.const 1 - i32.lt_s - drop - local.get $1 - i32.const 0 - i32.le_s - if - local.get $0 - i32.const -1 - i32.eq - if - i32.const -1 - i32.const 1 - local.get $1 - i32.const 1 - i32.and - select - return - end - local.get $1 - i32.const 0 - i32.eq - local.get $0 - i32.const 1 - i32.eq - i32.or - return - else - local.get $1 - i32.const 1 - i32.eq - if - local.get $0 - return - else - local.get $1 - i32.const 2 - i32.eq - if - local.get $0 - local.get $0 - i32.mul - return - else - local.get $1 - i32.const 32 - i32.lt_s - if - i32.const 32 - local.get $1 - i32.clz - i32.sub - local.set $3 - block $break|0 - block $case4|0 - block $case3|0 - block $case2|0 - block $case1|0 - block $case0|0 - local.get $3 - local.set $4 - local.get $4 - i32.const 5 - i32.eq - br_if $case0|0 - local.get $4 - i32.const 4 - i32.eq - br_if $case1|0 - local.get $4 - i32.const 3 - i32.eq - br_if $case2|0 - local.get $4 - i32.const 2 - i32.eq - br_if $case3|0 - local.get $4 - i32.const 1 - i32.eq - br_if $case4|0 - br $break|0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - end - local.get $2 - return - end - end - end - end - loop $while-continue|1 - local.get $1 - local.set $3 - local.get $3 - if - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - br $while-continue|1 - end - end - local.get $2 - ) (func $resolve-binary/Foo#constructor (param $0 i32) (result i32) local.get $0 i32.eqz @@ -5464,9 +5259,7 @@ call $~lib/builtins/abort unreachable end - i32.const 2 - i32.const 2 - call $~lib/math/ipow32 + i32.const 4 i32.const 10 call $~lib/number/I32#toString local.tee $26 @@ -5481,9 +5274,7 @@ call $~lib/builtins/abort unreachable end - f64.const 2 - f64.const 2 - call $~lib/math/NativeMath.pow + f64.const 4 i32.const 0 call $~lib/number/F64#toString local.tee $27 @@ -5498,9 +5289,7 @@ call $~lib/builtins/abort unreachable end - f64.const 2 - f64.const 2 - call $~lib/math/NativeMath.pow + f64.const 4 i32.const 0 call $~lib/number/F64#toString local.tee $28 diff --git a/tests/compiler/std/math.untouched.wat b/tests/compiler/std/math.untouched.wat index 271d353465..d62d404dc5 100644 --- a/tests/compiler/std/math.untouched.wat +++ b/tests/compiler/std/math.untouched.wat @@ -14,7 +14,6 @@ (type $i64_=>_none (func (param i64))) (type $f64_=>_none (func (param f64))) (type $i32_=>_i32 (func (param i32) (result i32))) - (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i64_i64_i64_i64_i64_i32_=>_i32 (func (param i64 i64 i64 i64 i64 i32) (result i32))) (type $f32_=>_i32 (func (param f32) (result i32))) (type $f32_i32_f32_f32_i32_=>_i32 (func (param f32 i32 f32 f32 i32) (result i32))) @@ -16213,211 +16212,6 @@ end local.get $2 ) - (func $~lib/math/ipow32 (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - i32.const 1 - local.set $2 - i32.const 0 - i32.const 1 - i32.lt_s - drop - local.get $1 - i32.const 0 - i32.le_s - if - local.get $0 - i32.const -1 - i32.eq - if - i32.const -1 - i32.const 1 - local.get $1 - i32.const 1 - i32.and - select - return - end - local.get $1 - i32.const 0 - i32.eq - local.get $0 - i32.const 1 - i32.eq - i32.or - return - else - local.get $1 - i32.const 1 - i32.eq - if - local.get $0 - return - else - local.get $1 - i32.const 2 - i32.eq - if - local.get $0 - local.get $0 - i32.mul - return - else - local.get $1 - i32.const 32 - i32.lt_s - if - i32.const 32 - local.get $1 - i32.clz - i32.sub - local.set $3 - block $break|0 - block $case4|0 - block $case3|0 - block $case2|0 - block $case1|0 - block $case0|0 - local.get $3 - local.set $4 - local.get $4 - i32.const 5 - i32.eq - br_if $case0|0 - local.get $4 - i32.const 4 - i32.eq - br_if $case1|0 - local.get $4 - i32.const 3 - i32.eq - br_if $case2|0 - local.get $4 - i32.const 2 - i32.eq - br_if $case3|0 - local.get $4 - i32.const 1 - i32.eq - br_if $case4|0 - br $break|0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - end - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - end - local.get $2 - return - end - end - end - end - loop $while-continue|1 - local.get $1 - local.set $3 - local.get $3 - if - local.get $1 - i32.const 1 - i32.and - if - local.get $2 - local.get $0 - i32.mul - local.set $2 - end - local.get $1 - i32.const 1 - i32.shr_u - local.set $1 - local.get $0 - local.get $0 - i32.mul - local.set $0 - br $while-continue|1 - end - end - local.get $2 - ) (func $start:std/math (local $0 f64) (local $1 i32) @@ -58784,117 +58578,37 @@ i32.eq drop i32.const 1 - i32.const 3 - call $~lib/math/ipow32 i32.const 1 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4082 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const -2 - i32.const 3 - call $~lib/math/ipow32 + drop + i32.const -8 i32.const -8 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4083 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const -1 - i32.const 0 - call $~lib/math/ipow32 + drop + i32.const 1 i32.const 1 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4084 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const -1 + drop i32.const -1 - call $~lib/math/ipow32 i32.const -1 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4085 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const -1 - i32.const -2 - call $~lib/math/ipow32 + drop + i32.const 1 i32.const 1 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4086 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i32.const -1 - i32.const -3 - call $~lib/math/ipow32 i32.const -1 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4087 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i32.const 0 - i32.const -2 - call $~lib/math/ipow32 i32.const 0 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4089 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i32.const 0 - i32.const -1 - call $~lib/math/ipow32 i32.const 0 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4090 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i32.const 1 i32.const 0 i32.const 0 @@ -58914,47 +58628,17 @@ i32.eq drop i32.const 0 - i32.const 2 - call $~lib/math/ipow32 i32.const 0 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4093 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i32.const 1 - i32.const -2 - call $~lib/math/ipow32 i32.const 1 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4095 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i32.const 1 - i32.const -1 - call $~lib/math/ipow32 i32.const 1 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4096 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i32.const 1 i32.const 0 i32.const 0 @@ -58974,267 +58658,81 @@ i32.eq drop i32.const 1 - i32.const 2 - call $~lib/math/ipow32 i32.const 1 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4099 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i32.const 1 - i32.const 3 - call $~lib/math/ipow32 - i32.const 24 - i32.shl - i32.const 24 - i32.shr_s i32.const 1 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4101 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const -2 - i32.const 3 - call $~lib/math/ipow32 - i32.const 24 - i32.shl - i32.const 24 - i32.shr_s + drop + i32.const -8 i32.const -8 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4102 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 4 - i32.const 7 - call $~lib/math/ipow32 - i32.const 65535 - i32.and + drop + i32.const 16384 i32.const 16384 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4103 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 4 - i32.const 8 - call $~lib/math/ipow32 + drop + i32.const 65536 i32.const 65535 i32.and i32.const 0 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4104 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i32.const 5 - i32.const 10 - call $~lib/math/ipow32 + drop + i32.const 9765625 i32.const 65535 i32.and i32.const 761 i32.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4105 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 0 - i64.const 0 - call $~lib/math/ipow64 + drop + i64.const 1 i64.const 1 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4107 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i64.const 0 - i64.const 1 - call $~lib/math/ipow64 i64.const 0 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4108 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i64.const 1 - i64.const 3 - call $~lib/math/ipow64 i64.const 1 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4109 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 2 - i64.const 3 - call $~lib/math/ipow64 + drop + i64.const 8 i64.const 8 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4110 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 4294967295 - i64.const 3 - call $~lib/math/ipow64 + drop + i64.const 12884901887 i64.const 12884901887 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4111 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 65535 - i64.const 3 - call $~lib/math/ipow64 + drop + i64.const 281462092005375 i64.const 281462092005375 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4112 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 65535 - i64.const 8 - call $~lib/math/ipow64 + drop + i64.const -15762478437236735 i64.const -15762478437236735 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4113 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 61731 - i64.const 4 - call $~lib/math/ipow64 + drop + i64.const -3925184889716469295 i64.const -3925184889716469295 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4114 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 61731 - i64.const 4 - call $~lib/math/ipow64 + drop + i64.const -3925184889716469295 i64.const -3925184889716469295 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4115 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 57055 - i64.const 3 - call $~lib/math/ipow64 - i64.const 339590 - i64.const 3 - call $~lib/math/ipow64 + drop + i64.const 185729602441375 + i64.const 39161983393079000 i64.add - i64.const 340126 - i64.const 3 - call $~lib/math/ipow64 + i64.const 39347712995520376 i64.ne - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4117 - i32.const 1 - call $~lib/builtins/abort - unreachable - end - i64.const 57055 - i64.const 3 - call $~lib/math/ipow64 - i64.const 339590 - i64.const 3 - call $~lib/math/ipow64 + drop + i64.const 185729602441375 + i64.const 39161983393079000 i64.add i64.const 39347712995520375 i64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4118 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop i32.const 1 f64.convert_i32_u f64.const 0.5 @@ -59280,34 +58778,14 @@ call $~lib/builtins/abort unreachable end - f64.const 0 - f64.const 0 - call $~lib/math/NativeMath.pow f64.const 1 - f64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4123 - i32.const 1 - call $~lib/builtins/abort - unreachable - end f64.const 1 + f64.eq + drop f64.const 1 - call $~lib/math/NativeMath.pow f64.const 1 f64.eq - i32.eqz - if - i32.const 0 - i32.const 32 - i32.const 4124 - i32.const 1 - call $~lib/builtins/abort - unreachable - end + drop ) (func $~start call $start:std/math From 9f68a2c486bbecd524f026a6ded29a61bb1a6ebc Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Thu, 19 Nov 2020 17:46:33 +0200 Subject: [PATCH 6/6] avoid precompute in some tests --- tests/compiler/std/math.optimized.wat | 372 ++++++++++++++--- tests/compiler/std/math.ts | 129 +++--- tests/compiler/std/math.untouched.wat | 559 ++++++++++++++++++++++---- 3 files changed, 870 insertions(+), 190 deletions(-) diff --git a/tests/compiler/std/math.optimized.wat b/tests/compiler/std/math.optimized.wat index 2c341183ea..6744191378 100644 --- a/tests/compiler/std/math.optimized.wat +++ b/tests/compiler/std/math.optimized.wat @@ -15,6 +15,7 @@ (type $i64_i64_i64_i64_i64_=>_none (func (param i64 i64 i64 i64 i64))) (type $f64_=>_none (func (param f64))) (type $i32_=>_i32 (func (param i32) (result i32))) + (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i64_=>_i32 (func (param i64) (result i32))) (type $f64_=>_i32 (func (param f64) (result i32))) (type $i64_=>_i64 (func (param i64) (result i64))) @@ -80,6 +81,9 @@ (global $~lib/math/random_state1_32 (mut i32) (i32.const 0)) (global $~lib/math/NativeMath.sincos_sin (mut f64) (f64.const 0)) (global $~lib/math/NativeMath.sincos_cos (mut f64) (f64.const 0)) + (global $std/math/x (mut i64) (i64.const 0)) + (global $std/math/y (mut i32) (i32.const 0)) + (global $std/math/ux (mut i64) (i64.const 0)) (export "memory" (memory $0)) (start $~start) (func $~lib/math/NativeMath.scalbn (param $0 f64) (param $1 i32) (result f64) @@ -10836,6 +10840,35 @@ end local.get $2 ) + (func $~lib/math/ipow32 (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + i32.const 1 + local.set $2 + loop $while-continue|0 + local.get $1 + if + local.get $0 + local.get $2 + i32.mul + local.get $2 + local.get $1 + i32.const 1 + i32.and + select + local.set $2 + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + br $while-continue|0 + end + end + local.get $2 + ) (func $start:std/math (local $0 f64) (local $1 i32) @@ -48990,6 +49023,8 @@ unreachable end i64.const 0 + global.set $std/math/x + i64.const 0 i64.const 0 call $~lib/math/ipow64 i64.const 1 @@ -48997,12 +49032,12 @@ if i32.const 0 i32.const 1056 - i32.const 4044 + i32.const 4047 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 0 + global.get $std/math/x i64.const 1 call $~lib/math/ipow64 i64.eqz @@ -49010,12 +49045,12 @@ if i32.const 0 i32.const 1056 - i32.const 4045 + i32.const 4048 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 0 + global.get $std/math/x i64.const 2 call $~lib/math/ipow64 i64.eqz @@ -49023,12 +49058,12 @@ if i32.const 0 i32.const 1056 - i32.const 4046 + i32.const 4049 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 0 + global.get $std/math/x i64.const 3 call $~lib/math/ipow64 i64.eqz @@ -49036,12 +49071,14 @@ if i32.const 0 i32.const 1056 - i32.const 4047 + i32.const 4050 i32.const 1 call $~lib/builtins/abort unreachable end i64.const 1 + global.set $std/math/x + i64.const 1 i64.const 0 call $~lib/math/ipow64 i64.const 1 @@ -49049,12 +49086,12 @@ if i32.const 0 i32.const 1056 - i32.const 4049 + i32.const 4053 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 1 + global.get $std/math/x i64.const 1 call $~lib/math/ipow64 i64.const 1 @@ -49062,12 +49099,12 @@ if i32.const 0 i32.const 1056 - i32.const 4050 + i32.const 4054 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 1 + global.get $std/math/x i64.const 2 call $~lib/math/ipow64 i64.const 1 @@ -49075,12 +49112,12 @@ if i32.const 0 i32.const 1056 - i32.const 4051 + i32.const 4055 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 1 + global.get $std/math/x i64.const 3 call $~lib/math/ipow64 i64.const 1 @@ -49088,12 +49125,14 @@ if i32.const 0 i32.const 1056 - i32.const 4052 + i32.const 4056 i32.const 1 call $~lib/builtins/abort unreachable end i64.const 2 + global.set $std/math/x + i64.const 2 i64.const 0 call $~lib/math/ipow64 i64.const 1 @@ -49101,12 +49140,12 @@ if i32.const 0 i32.const 1056 - i32.const 4054 + i32.const 4059 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 2 + global.get $std/math/x i64.const 1 call $~lib/math/ipow64 i64.const 2 @@ -49114,12 +49153,12 @@ if i32.const 0 i32.const 1056 - i32.const 4055 + i32.const 4060 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 2 + global.get $std/math/x i64.const 2 call $~lib/math/ipow64 i64.const 4 @@ -49127,12 +49166,12 @@ if i32.const 0 i32.const 1056 - i32.const 4056 + i32.const 4061 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 2 + global.get $std/math/x i64.const 3 call $~lib/math/ipow64 i64.const 8 @@ -49140,12 +49179,14 @@ if i32.const 0 i32.const 1056 - i32.const 4057 + i32.const 4062 i32.const 1 call $~lib/builtins/abort unreachable end i64.const -1 + global.set $std/math/x + i64.const -1 i64.const 0 call $~lib/math/ipow64 i64.const 1 @@ -49153,12 +49194,12 @@ if i32.const 0 i32.const 1056 - i32.const 4059 + i32.const 4065 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const -1 + global.get $std/math/x i64.const 1 call $~lib/math/ipow64 i64.const -1 @@ -49166,12 +49207,12 @@ if i32.const 0 i32.const 1056 - i32.const 4060 + i32.const 4066 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const -1 + global.get $std/math/x i64.const 2 call $~lib/math/ipow64 i64.const 1 @@ -49179,12 +49220,12 @@ if i32.const 0 i32.const 1056 - i32.const 4061 + i32.const 4067 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const -1 + global.get $std/math/x i64.const 3 call $~lib/math/ipow64 i64.const -1 @@ -49192,12 +49233,14 @@ if i32.const 0 i32.const 1056 - i32.const 4062 + i32.const 4068 i32.const 1 call $~lib/builtins/abort unreachable end i64.const -2 + global.set $std/math/x + i64.const -2 i64.const 0 call $~lib/math/ipow64 i64.const 1 @@ -49205,12 +49248,12 @@ if i32.const 0 i32.const 1056 - i32.const 4064 + i32.const 4071 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const -2 + global.get $std/math/x i64.const 1 call $~lib/math/ipow64 i64.const -2 @@ -49218,12 +49261,12 @@ if i32.const 0 i32.const 1056 - i32.const 4065 + i32.const 4072 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const -2 + global.get $std/math/x i64.const 2 call $~lib/math/ipow64 i64.const 4 @@ -49231,12 +49274,12 @@ if i32.const 0 i32.const 1056 - i32.const 4066 + i32.const 4073 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const -2 + global.get $std/math/x i64.const 3 call $~lib/math/ipow64 i64.const -8 @@ -49244,12 +49287,14 @@ if i32.const 0 i32.const 1056 - i32.const 4067 + i32.const 4074 i32.const 1 call $~lib/builtins/abort unreachable end i64.const 2 + global.set $std/math/x + i64.const 2 i64.const 63 call $~lib/math/ipow64 i64.const -9223372036854775808 @@ -49257,38 +49302,40 @@ if i32.const 0 i32.const 1056 - i32.const 4069 + i32.const 4077 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 3 - i64.const 40 + global.get $std/math/x + i64.const 64 call $~lib/math/ipow64 - i64.const -6289078614652622815 - i64.ne + i64.eqz + i32.eqz if i32.const 0 i32.const 1056 - i32.const 4070 + i32.const 4078 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 2 - i64.const 64 + i64.const 3 + global.set $std/math/x + i64.const 3 + i64.const 40 call $~lib/math/ipow64 - i64.eqz - i32.eqz + i64.const -6289078614652622815 + i64.ne if i32.const 0 i32.const 1056 - i32.const 4071 + i32.const 4081 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 3 + global.get $std/math/x i64.const 41 call $~lib/math/ipow64 i64.const -420491770248316829 @@ -49296,12 +49343,12 @@ if i32.const 0 i32.const 1056 - i32.const 4072 + i32.const 4082 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 3 + global.get $std/math/x i64.const 128 call $~lib/math/ipow64 i64.const -9204772141784466943 @@ -49309,12 +49356,14 @@ if i32.const 0 i32.const 1056 - i32.const 4073 + i32.const 4083 i32.const 1 call $~lib/builtins/abort unreachable end i64.const 1 + global.set $std/math/x + i64.const 1 i64.const -1 call $~lib/math/ipow64 i64.const 1 @@ -49322,12 +49371,14 @@ if i32.const 0 i32.const 1056 - i32.const 4075 + i32.const 4086 i32.const 1 call $~lib/builtins/abort unreachable end i64.const 2 + global.set $std/math/x + i64.const 2 i64.const -1 call $~lib/math/ipow64 i64.eqz @@ -49335,7 +49386,218 @@ if i32.const 0 i32.const 1056 - i32.const 4076 + i32.const 4089 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 0 + global.set $std/math/y + i32.const 0 + i32.const 0 + call $~lib/math/ipow32 + i32.const 1 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 4096 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $std/math/y + i32.const 1 + call $~lib/math/ipow32 + if + i32.const 0 + i32.const 1056 + i32.const 4097 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const 1 + global.set $std/math/y + i32.const 1 + i32.const 3 + call $~lib/math/ipow32 + i32.const 1 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 4100 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const -2 + global.set $std/math/y + i32.const -2 + i32.const 3 + call $~lib/math/ipow32 + i32.const -8 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 4103 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const -1 + global.set $std/math/y + i32.const -1 + i32.const 0 + call $~lib/math/ipow32 + i32.const 1 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 4106 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $std/math/y + i32.const -1 + call $~lib/math/ipow32 + i32.const -1 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 4107 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $std/math/y + i32.const -2 + call $~lib/math/ipow32 + i32.const 1 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 4108 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $std/math/y + i32.const -3 + call $~lib/math/ipow32 + i32.const -1 + i32.ne + if + i32.const 0 + i32.const 1056 + i32.const 4109 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 0 + global.set $std/math/ux + i64.const 0 + i64.const 0 + call $~lib/math/ipow64 + i64.const 1 + i64.ne + if + i32.const 0 + i32.const 1056 + i32.const 4131 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $std/math/ux + i64.const 1 + call $~lib/math/ipow64 + i64.eqz + i32.eqz + if + i32.const 0 + i32.const 1056 + i32.const 4132 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 1 + global.set $std/math/ux + i64.const 1 + i64.const 3 + call $~lib/math/ipow64 + i64.const 1 + i64.ne + if + i32.const 0 + i32.const 1056 + i32.const 4135 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 2 + global.set $std/math/ux + i64.const 2 + i64.const 3 + call $~lib/math/ipow64 + i64.const 8 + i64.ne + if + i32.const 0 + i32.const 1056 + i32.const 4138 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 4294967295 + global.set $std/math/ux + i64.const 4294967295 + i64.const 3 + call $~lib/math/ipow64 + i64.const 12884901887 + i64.ne + if + i32.const 0 + i32.const 1056 + i32.const 4141 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 65535 + global.set $std/math/ux + i64.const 65535 + i64.const 3 + call $~lib/math/ipow64 + i64.const 281462092005375 + i64.ne + if + i32.const 0 + i32.const 1056 + i32.const 4144 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $std/math/ux + i64.const 8 + call $~lib/math/ipow64 + i64.const -15762478437236735 + i64.ne + if + i32.const 0 + i32.const 1056 + i32.const 4145 i32.const 1 call $~lib/builtins/abort unreachable @@ -49348,7 +49610,7 @@ if i32.const 0 i32.const 1056 - i32.const 4120 + i32.const 4153 i32.const 1 call $~lib/builtins/abort unreachable @@ -49361,7 +49623,7 @@ if i32.const 0 i32.const 1056 - i32.const 4121 + i32.const 4154 i32.const 1 call $~lib/builtins/abort unreachable @@ -49374,7 +49636,7 @@ if i32.const 0 i32.const 1056 - i32.const 4122 + i32.const 4155 i32.const 1 call $~lib/builtins/abort unreachable diff --git a/tests/compiler/std/math.ts b/tests/compiler/std/math.ts index cae8f4c655..9e1fa58c30 100644 --- a/tests/compiler/std/math.ts +++ b/tests/compiler/std/math.ts @@ -4041,50 +4041,72 @@ assert(NativeMath.clz32(f64.EPSILON) == 32); // ipow64 ///////////////////////////////////////////////////////////////////////////////////// -assert(ipow64(0, 0) == 1); -assert(ipow64(0, 1) == 0); -assert(ipow64(0, 2) == 0); -assert(ipow64(0, 3) == 0); - -assert(ipow64(1, 0) == 1); -assert(ipow64(1, 1) == 1); -assert(ipow64(1, 2) == 1); -assert(ipow64(1, 3) == 1); - -assert(ipow64(2, 0) == 1); -assert(ipow64(2, 1) == 2); -assert(ipow64(2, 2) == 4); -assert(ipow64(2, 3) == 8); - -assert(ipow64(-1, 0) == 1); -assert(ipow64(-1, 1) == -1); -assert(ipow64(-1, 2) == 1); -assert(ipow64(-1, 3) == -1); - -assert(ipow64(-2, 0) == 1); -assert(ipow64(-2, 1) == -2); -assert(ipow64(-2, 2) == 4); -assert(ipow64(-2, 3) == -8); - -assert(ipow64(2, 63) == 9223372036854775808); -assert(ipow64(3, 40) == 12157665459056928801); -assert(ipow64(2, 64) == 0); // should overflow -assert(ipow64(3, 41) == -420491770248316829); // should overflow -assert(ipow64(3, 128) == -9204772141784466943); // should overflow - -assert(ipow64(1, -1) == 1); -assert(ipow64(2, -1) == 0); +var x: i64; + +x = 0; +assert(ipow64(x, 0) == 1); +assert(ipow64(x, 1) == 0); +assert(ipow64(x, 2) == 0); +assert(ipow64(x, 3) == 0); + +x = 1; +assert(ipow64(x, 0) == 1); +assert(ipow64(x, 1) == 1); +assert(ipow64(x, 2) == 1); +assert(ipow64(x, 3) == 1); + +x = 2; +assert(ipow64(x, 0) == 1); +assert(ipow64(x, 1) == 2); +assert(ipow64(x, 2) == 4); +assert(ipow64(x, 3) == 8); + +x = -1; +assert(ipow64(x, 0) == 1); +assert(ipow64(x, 1) == -1); +assert(ipow64(x, 2) == 1); +assert(ipow64(x, 3) == -1); + +x = -2; +assert(ipow64(x, 0) == 1); +assert(ipow64(x, 1) == -2); +assert(ipow64(x, 2) == 4); +assert(ipow64(x, 3) == -8); + +x = 2; +assert(ipow64(x, 63) == 9223372036854775808); +assert(ipow64(x, 64) == 0); + +x = 3; +assert(ipow64(x, 40) == 12157665459056928801); // should overflow +assert(ipow64(x, 41) == -420491770248316829); // should overflow +assert(ipow64(x, 128) == -9204772141784466943); // should overflow + +x = 1; +assert(ipow64(x, -1) == 1); + +x = 2; +assert(ipow64(x, -1) == 0); // integer pow operators -assert( 0 ** 0 == 1); -assert( 0 ** 1 == 0); -assert( 1 ** 3 == 1); -assert((-2) ** 3 == -8); -assert((-1) ** 0 == 1); -assert((-1) ** -1 == -1); -assert((-1) ** -2 == 1); -assert((-1) ** -3 == -1); +var y: i32; + +y = 0; +assert(y ** 0 == 1); +assert(y ** 1 == 0); + +y = 1; +assert(y ** 3 == 1); + +y = -2; +assert(y ** 3 == -8); + +y = -1; +assert(y ** 0 == 1); +assert(y ** -1 == -1); +assert(y ** -2 == 1); +assert(y ** -3 == -1); assert(false ** -2 == 0); assert(false ** -1 == 0); @@ -4104,13 +4126,24 @@ assert((4) ** 7 == 16384); assert((4) ** 8 == 0); // should overflow assert((5) ** 10 == 761); // should overflow -assert((0) ** 0 == 1); -assert((0) ** 1 == 0); -assert((1) ** 3 == 1); -assert((2) ** 3 == 8); -assert((0xFFFFFFFF) ** 3 == 12884901887); -assert((0xFFFF) ** 3 == 281462092005375); -assert((0xFFFF) ** 8 == 18430981595272314881); +let ux: u64; +ux = 0; +assert(ux ** 0 == 1); +assert(ux ** 1 == 0); + +ux = 1; +assert(ux ** 3 == 1); + +ux = 2; +assert(ux ** 3 == 8); + +ux = 0xFFFFFFFF; +assert(ux ** 3 == 12884901887); + +ux = 0xFFFF; +assert(ux ** 3 == 281462092005375); +assert(ux ** 8 == 18430981595272314881); + assert(0xF123 ** 4 as u64 == 14521559183993082321); assert(0xF123 as u64 ** 4 == 14521559183993082321); // Fermat's Last Theorem diff --git a/tests/compiler/std/math.untouched.wat b/tests/compiler/std/math.untouched.wat index d4fc4816dd..037276c89f 100644 --- a/tests/compiler/std/math.untouched.wat +++ b/tests/compiler/std/math.untouched.wat @@ -14,6 +14,7 @@ (type $i64_=>_none (func (param i64))) (type $f64_=>_none (func (param f64))) (type $i32_=>_i32 (func (param i32) (result i32))) + (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i64_i64_i64_i64_i64_i32_=>_i32 (func (param i64 i64 i64 i64 i64 i32) (result i32))) (type $f32_=>_i32 (func (param f32) (result i32))) (type $f32_i32_f32_f32_i32_=>_i32 (func (param f32 i32 f32 f32 i32) (result i32))) @@ -122,6 +123,9 @@ (global $~lib/builtins/f64.MAX_VALUE f64 (f64.const 1797693134862315708145274e284)) (global $~lib/builtins/f64.MAX_SAFE_INTEGER f64 (f64.const 9007199254740991)) (global $~lib/builtins/f64.EPSILON f64 (f64.const 2.220446049250313e-16)) + (global $std/math/x (mut i64) (i64.const 0)) + (global $std/math/y (mut i32) (i32.const 0)) + (global $std/math/ux (mut i64) (i64.const 0)) (export "memory" (memory $0)) (start $~start) (func $std/math/eulp (param $0 f64) (result i32) @@ -16212,6 +16216,211 @@ end local.get $2 ) + (func $~lib/math/ipow32 (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + i32.const 1 + local.set $2 + i32.const 0 + i32.const 1 + i32.lt_s + drop + local.get $1 + i32.const 0 + i32.le_s + if + local.get $0 + i32.const -1 + i32.eq + if + i32.const -1 + i32.const 1 + local.get $1 + i32.const 1 + i32.and + select + return + end + local.get $1 + i32.const 0 + i32.eq + local.get $0 + i32.const 1 + i32.eq + i32.or + return + else + local.get $1 + i32.const 1 + i32.eq + if + local.get $0 + return + else + local.get $1 + i32.const 2 + i32.eq + if + local.get $0 + local.get $0 + i32.mul + return + else + local.get $1 + i32.const 32 + i32.lt_s + if + i32.const 32 + local.get $1 + i32.clz + i32.sub + local.set $3 + block $break|0 + block $case4|0 + block $case3|0 + block $case2|0 + block $case1|0 + block $case0|0 + local.get $3 + local.set $4 + local.get $4 + i32.const 5 + i32.eq + br_if $case0|0 + local.get $4 + i32.const 4 + i32.eq + br_if $case1|0 + local.get $4 + i32.const 3 + i32.eq + br_if $case2|0 + local.get $4 + i32.const 2 + i32.eq + br_if $case3|0 + local.get $4 + i32.const 1 + i32.eq + br_if $case4|0 + br $break|0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + end + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + end + local.get $2 + return + end + end + end + end + loop $while-continue|1 + local.get $1 + local.set $3 + local.get $3 + if + local.get $1 + i32.const 1 + i32.and + if + local.get $2 + local.get $0 + i32.mul + local.set $2 + end + local.get $1 + i32.const 1 + i32.shr_u + local.set $1 + local.get $0 + local.get $0 + i32.mul + local.set $0 + br $while-continue|1 + end + end + local.get $2 + ) (func $start:std/math (local $0 f64) (local $1 i32) @@ -58182,6 +58391,8 @@ unreachable end i64.const 0 + global.set $std/math/x + global.get $std/math/x i64.const 0 call $~lib/math/ipow64 i64.const 1 @@ -58190,12 +58401,12 @@ if i32.const 0 i32.const 32 - i32.const 4044 + i32.const 4047 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 0 + global.get $std/math/x i64.const 1 call $~lib/math/ipow64 i64.const 0 @@ -58204,12 +58415,12 @@ if i32.const 0 i32.const 32 - i32.const 4045 + i32.const 4048 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 0 + global.get $std/math/x i64.const 2 call $~lib/math/ipow64 i64.const 0 @@ -58218,12 +58429,12 @@ if i32.const 0 i32.const 32 - i32.const 4046 + i32.const 4049 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 0 + global.get $std/math/x i64.const 3 call $~lib/math/ipow64 i64.const 0 @@ -58232,12 +58443,14 @@ if i32.const 0 i32.const 32 - i32.const 4047 + i32.const 4050 i32.const 1 call $~lib/builtins/abort unreachable end i64.const 1 + global.set $std/math/x + global.get $std/math/x i64.const 0 call $~lib/math/ipow64 i64.const 1 @@ -58246,12 +58459,12 @@ if i32.const 0 i32.const 32 - i32.const 4049 + i32.const 4053 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 1 + global.get $std/math/x i64.const 1 call $~lib/math/ipow64 i64.const 1 @@ -58260,12 +58473,12 @@ if i32.const 0 i32.const 32 - i32.const 4050 + i32.const 4054 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 1 + global.get $std/math/x i64.const 2 call $~lib/math/ipow64 i64.const 1 @@ -58274,12 +58487,12 @@ if i32.const 0 i32.const 32 - i32.const 4051 + i32.const 4055 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 1 + global.get $std/math/x i64.const 3 call $~lib/math/ipow64 i64.const 1 @@ -58288,12 +58501,14 @@ if i32.const 0 i32.const 32 - i32.const 4052 + i32.const 4056 i32.const 1 call $~lib/builtins/abort unreachable end i64.const 2 + global.set $std/math/x + global.get $std/math/x i64.const 0 call $~lib/math/ipow64 i64.const 1 @@ -58302,12 +58517,12 @@ if i32.const 0 i32.const 32 - i32.const 4054 + i32.const 4059 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 2 + global.get $std/math/x i64.const 1 call $~lib/math/ipow64 i64.const 2 @@ -58316,12 +58531,12 @@ if i32.const 0 i32.const 32 - i32.const 4055 + i32.const 4060 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 2 + global.get $std/math/x i64.const 2 call $~lib/math/ipow64 i64.const 4 @@ -58330,12 +58545,12 @@ if i32.const 0 i32.const 32 - i32.const 4056 + i32.const 4061 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 2 + global.get $std/math/x i64.const 3 call $~lib/math/ipow64 i64.const 8 @@ -58344,12 +58559,14 @@ if i32.const 0 i32.const 32 - i32.const 4057 + i32.const 4062 i32.const 1 call $~lib/builtins/abort unreachable end i64.const -1 + global.set $std/math/x + global.get $std/math/x i64.const 0 call $~lib/math/ipow64 i64.const 1 @@ -58358,12 +58575,12 @@ if i32.const 0 i32.const 32 - i32.const 4059 + i32.const 4065 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const -1 + global.get $std/math/x i64.const 1 call $~lib/math/ipow64 i64.const -1 @@ -58372,12 +58589,12 @@ if i32.const 0 i32.const 32 - i32.const 4060 + i32.const 4066 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const -1 + global.get $std/math/x i64.const 2 call $~lib/math/ipow64 i64.const 1 @@ -58386,12 +58603,12 @@ if i32.const 0 i32.const 32 - i32.const 4061 + i32.const 4067 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const -1 + global.get $std/math/x i64.const 3 call $~lib/math/ipow64 i64.const -1 @@ -58400,12 +58617,14 @@ if i32.const 0 i32.const 32 - i32.const 4062 + i32.const 4068 i32.const 1 call $~lib/builtins/abort unreachable end i64.const -2 + global.set $std/math/x + global.get $std/math/x i64.const 0 call $~lib/math/ipow64 i64.const 1 @@ -58414,12 +58633,12 @@ if i32.const 0 i32.const 32 - i32.const 4064 + i32.const 4071 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const -2 + global.get $std/math/x i64.const 1 call $~lib/math/ipow64 i64.const -2 @@ -58428,12 +58647,12 @@ if i32.const 0 i32.const 32 - i32.const 4065 + i32.const 4072 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const -2 + global.get $std/math/x i64.const 2 call $~lib/math/ipow64 i64.const 4 @@ -58442,12 +58661,12 @@ if i32.const 0 i32.const 32 - i32.const 4066 + i32.const 4073 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const -2 + global.get $std/math/x i64.const 3 call $~lib/math/ipow64 i64.const -8 @@ -58456,12 +58675,14 @@ if i32.const 0 i32.const 32 - i32.const 4067 + i32.const 4074 i32.const 1 call $~lib/builtins/abort unreachable end i64.const 2 + global.set $std/math/x + global.get $std/math/x i64.const 63 call $~lib/math/ipow64 i64.const -9223372036854775808 @@ -58470,40 +58691,42 @@ if i32.const 0 i32.const 32 - i32.const 4069 + i32.const 4077 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 3 - i64.const 40 + global.get $std/math/x + i64.const 64 call $~lib/math/ipow64 - i64.const -6289078614652622815 + i64.const 0 i64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4070 + i32.const 4078 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 2 - i64.const 64 + i64.const 3 + global.set $std/math/x + global.get $std/math/x + i64.const 40 call $~lib/math/ipow64 - i64.const 0 + i64.const -6289078614652622815 i64.eq i32.eqz if i32.const 0 i32.const 32 - i32.const 4071 + i32.const 4081 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 3 + global.get $std/math/x i64.const 41 call $~lib/math/ipow64 i64.const -420491770248316829 @@ -58512,12 +58735,12 @@ if i32.const 0 i32.const 32 - i32.const 4072 + i32.const 4082 i32.const 1 call $~lib/builtins/abort unreachable end - i64.const 3 + global.get $std/math/x i64.const 128 call $~lib/math/ipow64 i64.const -9204772141784466943 @@ -58526,12 +58749,14 @@ if i32.const 0 i32.const 32 - i32.const 4073 + i32.const 4083 i32.const 1 call $~lib/builtins/abort unreachable end i64.const 1 + global.set $std/math/x + global.get $std/math/x i64.const -1 call $~lib/math/ipow64 i64.const 1 @@ -58540,12 +58765,14 @@ if i32.const 0 i32.const 32 - i32.const 4075 + i32.const 4086 i32.const 1 call $~lib/builtins/abort unreachable end i64.const 2 + global.set $std/math/x + global.get $std/math/x i64.const -1 call $~lib/math/ipow64 i64.const 0 @@ -58554,53 +58781,131 @@ if i32.const 0 i32.const 32 - i32.const 4076 + i32.const 4089 i32.const 1 call $~lib/builtins/abort unreachable end - i32.const 1 - i32.const 0 i32.const 0 - i32.eq + global.set $std/math/y + global.get $std/math/y i32.const 0 - select + call $~lib/math/ipow32 i32.const 1 i32.eq - drop - i32.const 1 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4096 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $std/math/y i32.const 1 + call $~lib/math/ipow32 i32.const 0 i32.eq - i32.const 0 - select - i32.const 0 - i32.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4097 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i32.const 1 + global.set $std/math/y + global.get $std/math/y + i32.const 3 + call $~lib/math/ipow32 i32.const 1 i32.eq - drop - i32.const -8 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4100 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const -2 + global.set $std/math/y + global.get $std/math/y + i32.const 3 + call $~lib/math/ipow32 i32.const -8 i32.eq - drop - i32.const 1 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4103 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i32.const -1 + global.set $std/math/y + global.get $std/math/y + i32.const 0 + call $~lib/math/ipow32 i32.const 1 i32.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4106 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $std/math/y i32.const -1 + call $~lib/math/ipow32 i32.const -1 i32.eq - drop - i32.const 1 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4107 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $std/math/y + i32.const -2 + call $~lib/math/ipow32 i32.const 1 i32.eq - drop - i32.const -1 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4108 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $std/math/y + i32.const -3 + call $~lib/math/ipow32 i32.const -1 i32.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4109 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i32.const 0 i32.const 0 i32.eq @@ -58685,34 +58990,114 @@ i32.const 761 i32.eq drop - i64.const 1 + i64.const 0 + global.set $std/math/ux + global.get $std/math/ux + i64.const 0 + call $~lib/math/ipow64 i64.const 1 i64.eq - drop - i64.const 0 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4131 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $std/math/ux + i64.const 1 + call $~lib/math/ipow64 i64.const 0 i64.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4132 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i64.const 1 + global.set $std/math/ux + global.get $std/math/ux + i64.const 3 + call $~lib/math/ipow64 i64.const 1 i64.eq - drop - i64.const 8 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4135 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 2 + global.set $std/math/ux + global.get $std/math/ux + i64.const 3 + call $~lib/math/ipow64 i64.const 8 i64.eq - drop - i64.const 12884901887 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4138 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 4294967295 + global.set $std/math/ux + global.get $std/math/ux + i64.const 3 + call $~lib/math/ipow64 i64.const 12884901887 i64.eq - drop - i64.const 281462092005375 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4141 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 65535 + global.set $std/math/ux + global.get $std/math/ux + i64.const 3 + call $~lib/math/ipow64 i64.const 281462092005375 i64.eq - drop - i64.const -15762478437236735 + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4144 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + global.get $std/math/ux + i64.const 8 + call $~lib/math/ipow64 i64.const -15762478437236735 i64.eq - drop + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4145 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i64.const -3925184889716469295 i64.const -3925184889716469295 i64.eq @@ -58743,7 +59128,7 @@ if i32.const 0 i32.const 32 - i32.const 4120 + i32.const 4153 i32.const 1 call $~lib/builtins/abort unreachable @@ -58758,7 +59143,7 @@ if i32.const 0 i32.const 32 - i32.const 4121 + i32.const 4154 i32.const 1 call $~lib/builtins/abort unreachable @@ -58773,7 +59158,7 @@ if i32.const 0 i32.const 32 - i32.const 4122 + i32.const 4155 i32.const 1 call $~lib/builtins/abort unreachable