authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-27 19:05:51-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-27 19:11:55-07:00
loga71d00a4d504edfdb09cd169d29ca1bbc0b909c4
tree1b4f5a419ee46ccc26d605f00109f026d9a40c26
parent0b8bd9b2b4f609fb4ae7d31da7e7a0fd4f5ad987

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.

1 files changed, 7 insertions(+), 8 deletions(-)

lib/std/crypto/25519/field.zig+7-8
...@@ -341,7 +341,7 @@ pub const Fe = struct {...@@ -341,7 +341,7 @@ pub const Fe = struct {
341 }341 }
342342
343 /// Square a field element `n` times343 /// Square a field element `n` times
344 inline fn sqn(a: Fe, comptime n: comptime_int) Fe {344 fn sqn(a: Fe, n: usize) Fe {
345 var i: usize = 0;345 var i: usize = 0;
346 var fe = a;346 var fe = a;
347 while (i < n) : (i += 1) {347 while (i < n) : (i += 1) {
...@@ -390,13 +390,12 @@ pub const Fe = struct {...@@ -390,13 +390,12 @@ pub const Fe = struct {
390 const _11 = a.mul(a.sq());390 const _11 = a.mul(a.sq());
391 const _1111 = _11.mul(_11.sq().sq());391 const _1111 = _11.mul(_11.sq().sq());
392 const _11111111 = _1111.mul(_1111.sq().sq().sq().sq());392 const _11111111 = _1111.mul(_1111.sq().sq().sq().sq());
393 var t = _11111111.sqn(2).mul(_11);393 const u = _11111111.sqn(2).mul(_11);
394 const u = t;394 const t = u.sqn(10).mul(u).sqn(10).mul(u);
395 t = t.sqn(10).mul(u).sqn(10).mul(u);395 const t2 = t.sqn(30).mul(t);
396 t = t.sqn(30).mul(t);396 const t3 = t2.sqn(60).mul(t2);
397 t = t.sqn(60).mul(t);397 const t4 = t3.sqn(120).mul(t3).sqn(10).mul(u).sqn(3).mul(_11).sq();
398 t = t.sqn(120).mul(t).sqn(10).mul(u).sqn(3).mul(_11).sq();398 return @bitCast(bool, @truncate(u1, ~(t4.toBytes()[1] & 1)));
399 return @bitCast(bool, @truncate(u1, ~(t.toBytes()[1] & 1)));
400 }399 }
401400
402 fn uncheckedSqrt(x2: Fe) Fe {401 fn uncheckedSqrt(x2: Fe) Fe {