authorgravatar for 75577902+AndrewKraevskii@users.noreply.github.comАндрей Краевский <75577902+AndrewKraevskii@users.noreply.github.com> 2024-04-13 13:06:23+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-04-13 03:06:23-07:00
log7cc0e6d4cd5d699d5377cf47ee27a2e089d046bf
treebacde8ab8eb49a46301c0ce3293a58166a99933b
parent4fac5bd601da12140586115dc9ddc6a92577ff6d
signaturebadge-check Signed by PGP key B5690EEEBB952194

std: fix big int llshr to respect aliasing (#19612)


2 files changed, 19 insertions(+), 6 deletions(-)

lib/std/math/big/int.zig+6-6
...@@ -3776,19 +3776,19 @@ fn llshr(r: []Limb, a: []const Limb, shift: usize) void {...@@ -3776,19 +3776,19 @@ fn llshr(r: []Limb, a: []const Limb, shift: usize) void {
3776 const limb_shift = shift / limb_bits;3776 const limb_shift = shift / limb_bits;
3777 const interior_limb_shift = @as(Log2Limb, @truncate(shift));3777 const interior_limb_shift = @as(Log2Limb, @truncate(shift));
37783778
3779 var carry: Limb = 0;
3780 var i: usize = 0;3779 var i: usize = 0;
3781 while (i < a.len - limb_shift) : (i += 1) {3780 while (i < a.len - limb_shift) : (i += 1) {
3782 const src_i = a.len - i - 1;3781 const dst_i = i;
3783 const dst_i = src_i - limb_shift;3782 const src_i = dst_i + limb_shift;
37843783
3785 const src_digit = a[src_i];3784 const src_digit = a[src_i];
3786 r[dst_i] = carry | (src_digit >> interior_limb_shift);3785 const src_digit_next = if (src_i + 1 < a.len) a[src_i + 1] else 0;
3787 carry = @call(.always_inline, math.shl, .{3786 const carry = @call(.always_inline, math.shl, .{
3788 Limb,3787 Limb,
3789 src_digit,3788 src_digit_next,
3790 limb_bits - @as(Limb, @intCast(interior_limb_shift)),3789 limb_bits - @as(Limb, @intCast(interior_limb_shift)),
3791 });3790 });
3791 r[dst_i] = carry | (src_digit >> interior_limb_shift);
3792 }3792 }
3793}3793}
37943794
lib/std/math/big/int_test.zig+13
...@@ -2019,6 +2019,19 @@ test "shift-right multi" {...@@ -2019,6 +2019,19 @@ test "shift-right multi" {
2019 try a.shiftRight(&a, 63);2019 try a.shiftRight(&a, 63);
2020 try a.shiftRight(&a, 2);2020 try a.shiftRight(&a, 2);
2021 try testing.expect(a.eqlZero());2021 try testing.expect(a.eqlZero());
2022
2023 try a.set(0xffff0000eeee1111dddd2222cccc3333000000000000000000000);
2024 try a.shiftRight(&a, 84);
2025 const string = try a.toString(
2026 testing.allocator,
2027 16,
2028 .lower,
2029 );
2030 defer testing.allocator.free(string);
2031 try std.testing.expectEqualStrings(
2032 string,
2033 "ffff0000eeee1111dddd2222cccc3333",
2034 );
2022}2035}
20232036
2024test "shift-left single" {2037test "shift-left single" {