x86_64: rewrite scalar @mulWithOverflow

Closes #19607
This commit is contained in:
Jacob Young 2025-03-26 14:17:10 -04:00
parent 55ce756868
commit bc10131db1
3 changed files with 3645 additions and 5 deletions

File diff suppressed because it is too large Load Diff

View File

@ -787,7 +787,6 @@ fn should_not_be_zero(x: f128) !void {
test "umax wrapped squaring" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
{
@ -1050,13 +1049,13 @@ test "@mulWithOverflow bitsize > 32" {
}
test "@mulWithOverflow bitsize 128 bits" {
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
try testMulWithOverflow(u128, 3, 0x5555555555555555_5555555555555555, 0xffffffffffffffff_ffffffffffffffff, 0);
try testMulWithOverflow(u128, 3, 0x5555555555555555_5555555555555556, 2, 1);
@ -1070,13 +1069,19 @@ test "@mulWithOverflow bitsize 128 bits" {
try testMulWithOverflow(i128, 3, -0x2aaaaaaaaaaaaaaa_aaaaaaaaaaaaaaab, 0x7fffffffffffffff_ffffffffffffffff, 1);
try testMulWithOverflow(i128, -1, -1, 1, 0);
try testMulWithOverflow(i128, minInt(i128), minInt(i128), 0, 1);
try testMulWithOverflow(i128, 1 << 126, 1 << 1, -1 << 127, 1);
try testMulWithOverflow(i128, -1 << 105, 1 << 22, -1 << 127, 0);
try testMulWithOverflow(i128, 1 << 84, -1 << 43, -1 << 127, 0);
try testMulWithOverflow(i128, -1 << 63, -1 << 64, -1 << 127, 1);
}
test "@mulWithOverflow u256" {
test "@mulWithOverflow bitsize 256 bits" {
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
{
const const_lhs: u256 = 8035709466408580321693645878924206181189;
@ -1106,6 +1111,10 @@ test "@mulWithOverflow u256" {
try std.testing.expect(var_result[0] == const_result[0]);
try std.testing.expect(var_result[1] == const_result[1]);
}
try testMulWithOverflow(i256, 1 << 254, 1 << 1, -1 << 255, 1);
try testMulWithOverflow(i256, -1 << 212, 1 << 43, -1 << 255, 0);
try testMulWithOverflow(i256, 1 << 170, -1 << 85, -1 << 255, 0);
try testMulWithOverflow(i256, -1 << 128, -1 << 127, -1 << 255, 1);
}
fn testSubWithOverflow(comptime T: type, a: T, b: T, sub: T, bit: u1) !void {

View File

@ -5338,6 +5338,15 @@ test mulUnsafe {
try test_mul_unsafe.testIntVectors();
}
inline fn mulSafe(comptime Type: type, lhs: Type, rhs: Type) DoubleBits(Type) {
@setRuntimeSafety(true);
return @as(DoubleBits(Type), lhs) * rhs;
}
test mulSafe {
const test_mul_safe = binary(mulSafe, .{});
try test_mul_safe.testInts();
}
inline fn mulWrap(comptime Type: type, lhs: Type, rhs: Type) Type {
return lhs *% rhs;
}
@ -5460,6 +5469,14 @@ test subWithOverflow {
try test_sub_with_overflow.testInts();
}
inline fn mulWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, u1 } {
return @mulWithOverflow(lhs, rhs);
}
test mulWithOverflow {
const test_mul_with_overflow = binary(mulWithOverflow, .{});
try test_mul_with_overflow.testInts();
}
inline fn equal(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs == rhs) {
return lhs == rhs;
}