authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-07 02:11:49-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-07 03:00:08-05:00
logc1d16a2b80e258a126ed496dab09a8a7c26f8468
tree61f9e813ef2a078cce08ad216c07a41f80947549
parent6218e4004608000ba2e42e07ed1bd56745626820

compiler_rt: fix rare case in udivei4

Unsigned integers are never less than zero, and so zig helpfully deleted the entire case. :D Closes #14816

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

lib/compiler_rt/udivmodei4.zig+6-6
......@@ -79,16 +79,16 @@ fn divmod(q: ?[]u32, r: ?[]u32, u: []const u32, v: []const u32) !void {
7979 }
8080 break;
8181 }
82 var carry: u64 = 0;
82 var carry: i64 = 0;
8383 i = 0;
8484 while (i <= n) : (i += 1) {
8585 const p = qhat * limb(&vn, i);
8686 const t = limb(&un, i + j) - carry - @truncate(u32, p);
87 limb_set(&un, i + j, @truncate(u32, t));
88 carry = @intCast(u64, p >> 32) - @intCast(u64, t >> 32);
87 limb_set(&un, i + j, @truncate(u32, @bitCast(u64, t)));
88 carry = @intCast(i64, p >> 32) - @intCast(i64, t >> 32);
8989 }
90 const t = limb(&un, j + n + 1) - carry;
91 limb_set(&un, j + n + 1, @truncate(u32, t));
90 const t = limb(&un, j + n + 1) -% carry;
91 limb_set(&un, j + n + 1, @truncate(u32, @bitCast(u64, t)));
9292 if (q) |q_| limb_set(q_, j, @truncate(u32, qhat));
9393 if (t < 0) {
9494 if (q) |q_| limb_set(q_, j, limb(q_, j) - 1);
......@@ -99,7 +99,7 @@ fn divmod(q: ?[]u32, r: ?[]u32, u: []const u32, v: []const u32) !void {
9999 limb_set(&un, i + j, @truncate(u32, t2));
100100 carry2 = t2 >> 32;
101101 }
102 limb_set(un, j + n + 1, @truncate(u32, limb(&un, j + n + 1) + carry2));
102 limb_set(&un, j + n + 1, @truncate(u32, limb(&un, j + n + 1) + carry2));
103103 }
104104 if (j == 0) break;
105105 }
test/behavior/int_div.zig+20
......@@ -91,3 +91,23 @@ fn mod(comptime T: type, a: T, b: T) T {
9191fn rem(comptime T: type, a: T, b: T) T {
9292 return @rem(a, b);
9393}
94
95test "large integer division" {
96 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
97 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
98 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
99 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
100 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
101 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
102
103 {
104 var numerator: u256 = 99999999999999999997315645440;
105 var divisor: u256 = 10000000000000000000000000000;
106 try expect(numerator / divisor == 9);
107 }
108 {
109 var numerator: u256 = 99999999999999999999000000000000000000000;
110 var divisor: u256 = 10000000000000000000000000000000000000000;
111 try expect(numerator / divisor == 9);
112 }
113}