diff --git a/std/assembly/math.ts b/std/assembly/math.ts index 0b4313a61d..f43842b022 100644 --- a/std/assembly/math.ts +++ b/std/assembly/math.ts @@ -3080,6 +3080,9 @@ export namespace NativeMathf { export function ipow32(x: i32, e: i32): i32 { var out = 1; if (ASC_SHRINK_LEVEL < 1) { + if (x == 2) { + return select(1 << e, 0, e < 32); + } if (e <= 0) { if (x == -1) return select(-1, 1, e & 1); return i32(e == 0) | i32(x == 1); @@ -3129,6 +3132,9 @@ export function ipow32(x: i32, e: i32): i32 { export function ipow64(x: i64, e: i64): i64 { var out: i64 = 1; if (ASC_SHRINK_LEVEL < 1) { + if (x == 2) { + return select(1 << e, 0, e < 64); + } if (e <= 0) { if (x == -1) return select(-1, 1, e & 1); return i64(e == 0) | i64(x == 1); diff --git a/tests/compiler/binary.untouched.wat b/tests/compiler/binary.untouched.wat index b82faf2a06..edbaf499a8 100644 --- a/tests/compiler/binary.untouched.wat +++ b/tests/compiler/binary.untouched.wat @@ -31,6 +31,20 @@ i32.const 1 i32.lt_s drop + local.get $0 + i32.const 2 + i32.eq + if + i32.const 1 + local.get $1 + i32.shl + i32.const 0 + local.get $1 + i32.const 32 + i32.lt_u + select + return + end local.get $1 i32.const 0 i32.le_s diff --git a/tests/compiler/resolve-binary.untouched.wat b/tests/compiler/resolve-binary.untouched.wat index e91ac055a7..d4b29ac4f9 100644 --- a/tests/compiler/resolve-binary.untouched.wat +++ b/tests/compiler/resolve-binary.untouched.wat @@ -6429,6 +6429,20 @@ i32.const 1 i32.lt_s drop + local.get $0 + i32.const 2 + i32.eq + if + i32.const 1 + local.get $1 + i32.shl + i32.const 0 + local.get $1 + i32.const 32 + i32.lt_u + select + return + end local.get $1 i32.const 0 i32.le_s diff --git a/tests/compiler/std/math.optimized.wat b/tests/compiler/std/math.optimized.wat index c0505461dd..4db83421ff 100644 --- a/tests/compiler/std/math.optimized.wat +++ b/tests/compiler/std/math.optimized.wat @@ -49372,6 +49372,32 @@ call $~lib/builtins/abort unreachable end + i64.const 2 + i64.const 64 + call $~lib/math/ipow64 + i64.eqz + i32.eqz + if + i32.const 0 + i32.const 1056 + i32.const 4077 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 2 + i64.const 128 + call $~lib/math/ipow64 + i64.eqz + i32.eqz + if + i32.const 0 + i32.const 1056 + i32.const 4078 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i32.const 1 i32.const 3 call $~lib/math/ipow32 @@ -49380,7 +49406,7 @@ if i32.const 0 i32.const 1056 - i32.const 4082 + i32.const 4084 i32.const 1 call $~lib/builtins/abort unreachable @@ -49393,7 +49419,7 @@ if i32.const 0 i32.const 1056 - i32.const 4083 + i32.const 4085 i32.const 1 call $~lib/builtins/abort unreachable @@ -49406,7 +49432,7 @@ if i32.const 0 i32.const 1056 - i32.const 4084 + i32.const 4086 i32.const 1 call $~lib/builtins/abort unreachable @@ -49419,7 +49445,7 @@ if i32.const 0 i32.const 1056 - i32.const 4085 + i32.const 4087 i32.const 1 call $~lib/builtins/abort unreachable @@ -49432,7 +49458,7 @@ if i32.const 0 i32.const 1056 - i32.const 4086 + i32.const 4088 i32.const 1 call $~lib/builtins/abort unreachable @@ -49445,7 +49471,7 @@ if i32.const 0 i32.const 1056 - i32.const 4087 + i32.const 4089 i32.const 1 call $~lib/builtins/abort unreachable @@ -49456,7 +49482,7 @@ if i32.const 0 i32.const 1056 - i32.const 4089 + i32.const 4091 i32.const 1 call $~lib/builtins/abort unreachable @@ -49467,7 +49493,7 @@ if i32.const 0 i32.const 1056 - i32.const 4090 + i32.const 4092 i32.const 1 call $~lib/builtins/abort unreachable @@ -49478,7 +49504,7 @@ if i32.const 0 i32.const 1056 - i32.const 4093 + i32.const 4095 i32.const 1 call $~lib/builtins/abort unreachable @@ -49491,7 +49517,7 @@ if i32.const 0 i32.const 1056 - i32.const 4095 + i32.const 4097 i32.const 1 call $~lib/builtins/abort unreachable @@ -49504,7 +49530,7 @@ if i32.const 0 i32.const 1056 - i32.const 4096 + i32.const 4098 i32.const 1 call $~lib/builtins/abort unreachable @@ -49517,7 +49543,7 @@ if i32.const 0 i32.const 1056 - i32.const 4099 + i32.const 4101 i32.const 1 call $~lib/builtins/abort unreachable @@ -49532,7 +49558,7 @@ if i32.const 0 i32.const 1056 - i32.const 4101 + i32.const 4103 i32.const 1 call $~lib/builtins/abort unreachable @@ -49547,7 +49573,7 @@ if i32.const 0 i32.const 1056 - i32.const 4102 + i32.const 4104 i32.const 1 call $~lib/builtins/abort unreachable @@ -49562,7 +49588,7 @@ if i32.const 0 i32.const 1056 - i32.const 4103 + i32.const 4105 i32.const 1 call $~lib/builtins/abort unreachable @@ -49575,7 +49601,7 @@ if i32.const 0 i32.const 1056 - i32.const 4104 + i32.const 4106 i32.const 1 call $~lib/builtins/abort unreachable @@ -49590,7 +49616,7 @@ if i32.const 0 i32.const 1056 - i32.const 4105 + i32.const 4107 i32.const 1 call $~lib/builtins/abort unreachable @@ -49603,7 +49629,7 @@ if i32.const 0 i32.const 1056 - i32.const 4107 + i32.const 4109 i32.const 1 call $~lib/builtins/abort unreachable @@ -49616,7 +49642,7 @@ if i32.const 0 i32.const 1056 - i32.const 4108 + i32.const 4110 i32.const 1 call $~lib/builtins/abort unreachable @@ -49629,7 +49655,7 @@ if i32.const 0 i32.const 1056 - i32.const 4109 + i32.const 4111 i32.const 1 call $~lib/builtins/abort unreachable @@ -49642,7 +49668,7 @@ if i32.const 0 i32.const 1056 - i32.const 4110 + i32.const 4112 i32.const 1 call $~lib/builtins/abort unreachable @@ -49655,7 +49681,7 @@ if i32.const 0 i32.const 1056 - i32.const 4111 + i32.const 4113 i32.const 1 call $~lib/builtins/abort unreachable @@ -49668,7 +49694,7 @@ if i32.const 0 i32.const 1056 - i32.const 4112 + i32.const 4114 i32.const 1 call $~lib/builtins/abort unreachable @@ -49681,7 +49707,7 @@ if i32.const 0 i32.const 1056 - i32.const 4113 + i32.const 4115 i32.const 1 call $~lib/builtins/abort unreachable @@ -49694,7 +49720,7 @@ if i32.const 0 i32.const 1056 - i32.const 4114 + i32.const 4116 i32.const 1 call $~lib/builtins/abort unreachable @@ -49707,7 +49733,7 @@ if i32.const 0 i32.const 1056 - i32.const 4115 + i32.const 4117 i32.const 1 call $~lib/builtins/abort unreachable @@ -49726,7 +49752,7 @@ if i32.const 0 i32.const 1056 - i32.const 4117 + i32.const 4119 i32.const 1 call $~lib/builtins/abort unreachable @@ -49743,7 +49769,7 @@ if i32.const 0 i32.const 1056 - i32.const 4118 + i32.const 4120 i32.const 1 call $~lib/builtins/abort unreachable @@ -49756,7 +49782,7 @@ if i32.const 0 i32.const 1056 - i32.const 4120 + i32.const 4122 i32.const 1 call $~lib/builtins/abort unreachable @@ -49769,7 +49795,7 @@ if i32.const 0 i32.const 1056 - i32.const 4121 + i32.const 4123 i32.const 1 call $~lib/builtins/abort unreachable @@ -49782,7 +49808,7 @@ if i32.const 0 i32.const 1056 - i32.const 4122 + i32.const 4124 i32.const 1 call $~lib/builtins/abort unreachable @@ -49795,7 +49821,7 @@ if i32.const 0 i32.const 1056 - i32.const 4123 + i32.const 4125 i32.const 1 call $~lib/builtins/abort unreachable @@ -49808,7 +49834,7 @@ if i32.const 0 i32.const 1056 - i32.const 4124 + i32.const 4126 i32.const 1 call $~lib/builtins/abort unreachable diff --git a/tests/compiler/std/math.ts b/tests/compiler/std/math.ts index cae8f4c655..b2f6dbba38 100644 --- a/tests/compiler/std/math.ts +++ b/tests/compiler/std/math.ts @@ -4074,6 +4074,8 @@ assert(ipow64(3, 128) == -9204772141784466943); // should overflow assert(ipow64(1, -1) == 1); assert(ipow64(2, -1) == 0); +assert(ipow64(2, 64) == 0); +assert(ipow64(2, 128) == 0); // integer pow operators diff --git a/tests/compiler/std/math.untouched.wat b/tests/compiler/std/math.untouched.wat index 534a2f1300..5d6d522e97 100644 --- a/tests/compiler/std/math.untouched.wat +++ b/tests/compiler/std/math.untouched.wat @@ -15977,6 +15977,20 @@ i32.const 1 i32.lt_s drop + local.get $0 + i64.const 2 + i64.eq + if + i64.const 1 + local.get $1 + i64.shl + i64.const 0 + local.get $1 + i64.const 64 + i64.lt_u + select + return + end local.get $1 i64.const 0 i64.le_s @@ -16226,6 +16240,20 @@ i32.const 1 i32.lt_s drop + local.get $0 + i32.const 2 + i32.eq + if + i32.const 1 + local.get $1 + i32.shl + i32.const 0 + local.get $1 + i32.const 32 + i32.lt_u + select + return + end local.get $1 i32.const 0 i32.le_s @@ -58768,6 +58796,34 @@ call $~lib/builtins/abort unreachable end + i64.const 2 + i64.const 64 + call $~lib/math/ipow64 + i64.const 0 + i64.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4077 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + i64.const 2 + i64.const 128 + call $~lib/math/ipow64 + i64.const 0 + i64.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4078 + i32.const 1 + call $~lib/builtins/abort + unreachable + end i32.const 1 i32.const 0 i32.const 0 @@ -58795,7 +58851,7 @@ if i32.const 0 i32.const 32 - i32.const 4082 + i32.const 4084 i32.const 1 call $~lib/builtins/abort unreachable @@ -58809,7 +58865,7 @@ if i32.const 0 i32.const 32 - i32.const 4083 + i32.const 4085 i32.const 1 call $~lib/builtins/abort unreachable @@ -58823,7 +58879,7 @@ if i32.const 0 i32.const 32 - i32.const 4084 + i32.const 4086 i32.const 1 call $~lib/builtins/abort unreachable @@ -58837,7 +58893,7 @@ if i32.const 0 i32.const 32 - i32.const 4085 + i32.const 4087 i32.const 1 call $~lib/builtins/abort unreachable @@ -58851,7 +58907,7 @@ if i32.const 0 i32.const 32 - i32.const 4086 + i32.const 4088 i32.const 1 call $~lib/builtins/abort unreachable @@ -58865,7 +58921,7 @@ if i32.const 0 i32.const 32 - i32.const 4087 + i32.const 4089 i32.const 1 call $~lib/builtins/abort unreachable @@ -58879,7 +58935,7 @@ if i32.const 0 i32.const 32 - i32.const 4089 + i32.const 4091 i32.const 1 call $~lib/builtins/abort unreachable @@ -58893,7 +58949,7 @@ if i32.const 0 i32.const 32 - i32.const 4090 + i32.const 4092 i32.const 1 call $~lib/builtins/abort unreachable @@ -58925,7 +58981,7 @@ if i32.const 0 i32.const 32 - i32.const 4093 + i32.const 4095 i32.const 1 call $~lib/builtins/abort unreachable @@ -58939,7 +58995,7 @@ if i32.const 0 i32.const 32 - i32.const 4095 + i32.const 4097 i32.const 1 call $~lib/builtins/abort unreachable @@ -58953,7 +59009,7 @@ if i32.const 0 i32.const 32 - i32.const 4096 + i32.const 4098 i32.const 1 call $~lib/builtins/abort unreachable @@ -58985,7 +59041,7 @@ if i32.const 0 i32.const 32 - i32.const 4099 + i32.const 4101 i32.const 1 call $~lib/builtins/abort unreachable @@ -59003,7 +59059,7 @@ if i32.const 0 i32.const 32 - i32.const 4101 + i32.const 4103 i32.const 1 call $~lib/builtins/abort unreachable @@ -59021,7 +59077,7 @@ if i32.const 0 i32.const 32 - i32.const 4102 + i32.const 4104 i32.const 1 call $~lib/builtins/abort unreachable @@ -59037,7 +59093,7 @@ if i32.const 0 i32.const 32 - i32.const 4103 + i32.const 4105 i32.const 1 call $~lib/builtins/abort unreachable @@ -59053,7 +59109,7 @@ if i32.const 0 i32.const 32 - i32.const 4104 + i32.const 4106 i32.const 1 call $~lib/builtins/abort unreachable @@ -59069,7 +59125,7 @@ if i32.const 0 i32.const 32 - i32.const 4105 + i32.const 4107 i32.const 1 call $~lib/builtins/abort unreachable @@ -59083,7 +59139,7 @@ if i32.const 0 i32.const 32 - i32.const 4107 + i32.const 4109 i32.const 1 call $~lib/builtins/abort unreachable @@ -59097,7 +59153,7 @@ if i32.const 0 i32.const 32 - i32.const 4108 + i32.const 4110 i32.const 1 call $~lib/builtins/abort unreachable @@ -59111,7 +59167,7 @@ if i32.const 0 i32.const 32 - i32.const 4109 + i32.const 4111 i32.const 1 call $~lib/builtins/abort unreachable @@ -59125,7 +59181,7 @@ if i32.const 0 i32.const 32 - i32.const 4110 + i32.const 4112 i32.const 1 call $~lib/builtins/abort unreachable @@ -59139,7 +59195,7 @@ if i32.const 0 i32.const 32 - i32.const 4111 + i32.const 4113 i32.const 1 call $~lib/builtins/abort unreachable @@ -59153,7 +59209,7 @@ if i32.const 0 i32.const 32 - i32.const 4112 + i32.const 4114 i32.const 1 call $~lib/builtins/abort unreachable @@ -59167,7 +59223,7 @@ if i32.const 0 i32.const 32 - i32.const 4113 + i32.const 4115 i32.const 1 call $~lib/builtins/abort unreachable @@ -59181,7 +59237,7 @@ if i32.const 0 i32.const 32 - i32.const 4114 + i32.const 4116 i32.const 1 call $~lib/builtins/abort unreachable @@ -59195,7 +59251,7 @@ if i32.const 0 i32.const 32 - i32.const 4115 + i32.const 4117 i32.const 1 call $~lib/builtins/abort unreachable @@ -59215,7 +59271,7 @@ if i32.const 0 i32.const 32 - i32.const 4117 + i32.const 4119 i32.const 1 call $~lib/builtins/abort unreachable @@ -59233,7 +59289,7 @@ if i32.const 0 i32.const 32 - i32.const 4118 + i32.const 4120 i32.const 1 call $~lib/builtins/abort unreachable @@ -59248,7 +59304,7 @@ if i32.const 0 i32.const 32 - i32.const 4120 + i32.const 4122 i32.const 1 call $~lib/builtins/abort unreachable @@ -59263,7 +59319,7 @@ if i32.const 0 i32.const 32 - i32.const 4121 + i32.const 4123 i32.const 1 call $~lib/builtins/abort unreachable @@ -59278,7 +59334,7 @@ if i32.const 0 i32.const 32 - i32.const 4122 + i32.const 4124 i32.const 1 call $~lib/builtins/abort unreachable @@ -59292,7 +59348,7 @@ if i32.const 0 i32.const 32 - i32.const 4123 + i32.const 4125 i32.const 1 call $~lib/builtins/abort unreachable @@ -59306,7 +59362,7 @@ if i32.const 0 i32.const 32 - i32.const 4124 + i32.const 4126 i32.const 1 call $~lib/builtins/abort unreachable diff --git a/tests/compiler/std/operator-overloading.untouched.wat b/tests/compiler/std/operator-overloading.untouched.wat index 07ecfe8863..8a4203495e 100644 --- a/tests/compiler/std/operator-overloading.untouched.wat +++ b/tests/compiler/std/operator-overloading.untouched.wat @@ -2485,6 +2485,20 @@ i32.const 1 i32.lt_s drop + local.get $0 + i32.const 2 + i32.eq + if + i32.const 1 + local.get $1 + i32.shl + i32.const 0 + local.get $1 + i32.const 32 + i32.lt_u + select + return + end local.get $1 i32.const 0 i32.le_s diff --git a/tests/compiler/std/string.untouched.wat b/tests/compiler/std/string.untouched.wat index d57cdbc2a5..ca0d54db61 100644 --- a/tests/compiler/std/string.untouched.wat +++ b/tests/compiler/std/string.untouched.wat @@ -4310,6 +4310,20 @@ i32.const 1 i32.lt_s drop + local.get $0 + i32.const 2 + i32.eq + if + i32.const 1 + local.get $1 + i32.shl + i32.const 0 + local.get $1 + i32.const 32 + i32.lt_u + select + return + end local.get $1 i32.const 0 i32.le_s