diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-06-27 19:05:51 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-06-27 19:11:55 -0700 |
| commit | a71d00a4d504edfdb09cd169d29ca1bbc0b909c4 (patch) | |
| tree | 1b4f5a419ee46ccc26d605f00109f026d9a40c26 /lib | |
| parent | 0b8bd9b2b4f609fb4ae7d31da7e7a0fd4f5ad987 (diff) | |
| download | zig-a71d00a4d504edfdb09cd169d29ca1bbc0b909c4.tar.gz zig-a71d00a4d504edfdb09cd169d29ca1bbc0b909c4.zip | |
std.crypto.25519.field: avoid excessive inlining
This valid zig code produces reasonable LLVM IR, however, on the
wasm32-wasi target, when using the wasmtime runtime, the number of
locals of the `isSquare` function exceeds 50000, causing wasmtime
to refuse to execute the binary.
The `inline` keyword in Zig is intended to be used only where it is
semantically necessary; not as an optimization hint. Otherwise, this may
produce unwanted binary bloat for the -OReleaseSmall use case.
In the future, it is possible that we may end up with both `inline`
keyword, which operates as it does in status quo, and additionally
`callconv(.inline_hint)` which has no semantic impact, but may be
observed by optimization passes.
In this commit, I also cleaned up `isSquare` by eliminating an
unnecessary mutable variable, replacing it with several local constants.
Closes #11947.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/std/crypto/25519/field.zig | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/lib/std/crypto/25519/field.zig b/lib/std/crypto/25519/field.zig index ce021ffb2a..1a786e0c32 100644 --- a/lib/std/crypto/25519/field.zig +++ b/lib/std/crypto/25519/field.zig @@ -341,7 +341,7 @@ pub const Fe = struct { } /// Square a field element `n` times - inline fn sqn(a: Fe, comptime n: comptime_int) Fe { + fn sqn(a: Fe, n: usize) Fe { var i: usize = 0; var fe = a; while (i < n) : (i += 1) { @@ -390,13 +390,12 @@ pub const Fe = struct { const _11 = a.mul(a.sq()); const _1111 = _11.mul(_11.sq().sq()); const _11111111 = _1111.mul(_1111.sq().sq().sq().sq()); - var t = _11111111.sqn(2).mul(_11); - const u = t; - t = t.sqn(10).mul(u).sqn(10).mul(u); - t = t.sqn(30).mul(t); - t = t.sqn(60).mul(t); - t = t.sqn(120).mul(t).sqn(10).mul(u).sqn(3).mul(_11).sq(); - return @bitCast(bool, @truncate(u1, ~(t.toBytes()[1] & 1))); + const u = _11111111.sqn(2).mul(_11); + const t = u.sqn(10).mul(u).sqn(10).mul(u); + const t2 = t.sqn(30).mul(t); + const t3 = t2.sqn(60).mul(t2); + const t4 = t3.sqn(120).mul(t3).sqn(10).mul(u).sqn(3).mul(_11).sq(); + return @bitCast(bool, @truncate(u1, ~(t4.toBytes()[1] & 1))); } fn uncheckedSqrt(x2: Fe) Fe { |
