authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-11-29 13:40:57-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-11-29 23:30:38-07:00
logf4666678886c2a7a993ad30b63de4ff25594085a
tree45cbb5b3ebbe23a46e27b04aa5898a6c00ec4a61
parentceb0a632cfd6a4eada6bd27bf6a3754e95dcac86

stage2: fix crash on comptime lazy `@ctz` and `@clz`


3 files changed, 43 insertions(+), 24 deletions(-)

lib/std/math/big/int.zig+28
......@@ -2376,6 +2376,34 @@ pub const Const = struct {
23762376 pub fn eq(a: Const, b: Const) bool {
23772377 return order(a, b) == .eq;
23782378 }
2379
2380 pub fn clz(a: Const, bits: Limb) Limb {
2381 // Limbs are stored in little-endian order but we need
2382 // to iterate big-endian.
2383 var total_limb_lz: Limb = 0;
2384 var i: usize = a.limbs.len;
2385 const bits_per_limb = @sizeOf(Limb) * 8;
2386 while (i != 0) {
2387 i -= 1;
2388 const limb = a.limbs[i];
2389 const this_limb_lz = @clz(limb);
2390 total_limb_lz += this_limb_lz;
2391 if (this_limb_lz != bits_per_limb) break;
2392 }
2393 const total_limb_bits = a.limbs.len * bits_per_limb;
2394 return total_limb_lz + bits - total_limb_bits;
2395 }
2396
2397 pub fn ctz(a: Const) Limb {
2398 // Limbs are stored in little-endian order.
2399 var result: Limb = 0;
2400 for (a.limbs) |limb| {
2401 const limb_tz = @ctz(limb);
2402 result += limb_tz;
2403 if (limb_tz != @sizeOf(Limb) * 8) break;
2404 }
2405 return result;
2406 }
23792407};
23802408
23812409/// An arbitrary-precision big integer along with an allocator which manages the memory.
src/Sema.zig+1
......@@ -19299,6 +19299,7 @@ fn zirBitCount(
1929919299 .Int => {
1930019300 if (try sema.resolveMaybeUndefVal(operand)) |val| {
1930119301 if (val.isUndef()) return sema.addConstUndef(result_scalar_ty);
19302 try sema.resolveLazyValue(val);
1930219303 return sema.addIntUnsigned(result_scalar_ty, comptimeOp(val, operand_ty, target));
1930319304 } else {
1930419305 try sema.requireRuntimeBlock(block, src, operand_src);
src/value.zig+14-24
......@@ -1677,22 +1677,8 @@ pub const Value = extern union {
16771677 @panic("TODO implement i64 Value clz");
16781678 },
16791679 .int_big_positive => {
1680 // TODO: move this code into std lib big ints
16811680 const bigint = val.castTag(.int_big_positive).?.asBigInt();
1682 // Limbs are stored in little-endian order but we need
1683 // to iterate big-endian.
1684 var total_limb_lz: u64 = 0;
1685 var i: usize = bigint.limbs.len;
1686 const bits_per_limb = @sizeOf(std.math.big.Limb) * 8;
1687 while (i != 0) {
1688 i -= 1;
1689 const limb = bigint.limbs[i];
1690 const this_limb_lz = @clz(limb);
1691 total_limb_lz += this_limb_lz;
1692 if (this_limb_lz != bits_per_limb) break;
1693 }
1694 const total_limb_bits = bigint.limbs.len * bits_per_limb;
1695 return total_limb_lz + ty_bits - total_limb_bits;
1681 return bigint.clz(ty_bits);
16961682 },
16971683 .int_big_negative => {
16981684 @panic("TODO implement int_big_negative Value clz");
......@@ -1703,6 +1689,12 @@ pub const Value = extern union {
17031689 return ty_bits;
17041690 },
17051691
1692 .lazy_align, .lazy_size => {
1693 var bigint_buf: BigIntSpace = undefined;
1694 const bigint = val.toBigIntAdvanced(&bigint_buf, target, null) catch unreachable;
1695 return bigint.clz(ty_bits);
1696 },
1697
17061698 else => unreachable,
17071699 }
17081700 }
......@@ -1721,16 +1713,8 @@ pub const Value = extern union {
17211713 @panic("TODO implement i64 Value ctz");
17221714 },
17231715 .int_big_positive => {
1724 // TODO: move this code into std lib big ints
17251716 const bigint = val.castTag(.int_big_positive).?.asBigInt();
1726 // Limbs are stored in little-endian order.
1727 var result: u64 = 0;
1728 for (bigint.limbs) |limb| {
1729 const limb_tz = @ctz(limb);
1730 result += limb_tz;
1731 if (limb_tz != @sizeOf(std.math.big.Limb) * 8) break;
1732 }
1733 return result;
1717 return bigint.ctz();
17341718 },
17351719 .int_big_negative => {
17361720 @panic("TODO implement int_big_negative Value ctz");
......@@ -1741,6 +1725,12 @@ pub const Value = extern union {
17411725 return ty_bits;
17421726 },
17431727
1728 .lazy_align, .lazy_size => {
1729 var bigint_buf: BigIntSpace = undefined;
1730 const bigint = val.toBigIntAdvanced(&bigint_buf, target, null) catch unreachable;
1731 return bigint.ctz();
1732 },
1733
17441734 else => unreachable,
17451735 }
17461736 }