compiler_rt: fix f80 comparisons

This corrects comparisons between negative numbers.
This commit is contained in:
Carl Åstholm 2023-08-20 23:47:06 +02:00 committed by Andrew Kelley
parent f74e10cd47
commit 60fc18bd1c
2 changed files with 34 additions and 1 deletions

View File

@ -89,7 +89,7 @@ pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT {
} else {
const a_fraction = a_rep.fraction | (@as(u80, a_rep.exp) << sig_bits);
const b_fraction = b_rep.fraction | (@as(u80, b_rep.exp) << sig_bits);
if (a_fraction < b_fraction) {
if ((a_fraction < b_fraction) == (a_rep.exp & sign_bit == 0)) {
return .Less;
} else {
return .Greater;
@ -97,6 +97,17 @@ pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT {
}
}
test "cmp_f80" {
inline for (.{ LE, GE }) |RT| {
try std.testing.expect(cmp_f80(RT, 1.0, 1.0) == RT.Equal);
try std.testing.expect(cmp_f80(RT, 0.0, -0.0) == RT.Equal);
try std.testing.expect(cmp_f80(RT, 2.0, 4.0) == RT.Less);
try std.testing.expect(cmp_f80(RT, 2.0, -4.0) == RT.Greater);
try std.testing.expect(cmp_f80(RT, -2.0, -4.0) == RT.Greater);
try std.testing.expect(cmp_f80(RT, -2.0, 4.0) == RT.Less);
}
}
pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 {
const rep_t = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);

View File

@ -70,6 +70,28 @@ fn testDifferentSizedFloatComparisons() !void {
try expect(a < b);
}
test "f80 comparisons" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
try expect(compareF80(0.0, .eq, -0.0));
try expect(compareF80(0.0, .lte, -0.0));
try expect(compareF80(0.0, .gte, -0.0));
try expect(compareF80(1.0, .neq, -1.0));
try expect(compareF80(2.0, .lt, 4.0));
try expect(compareF80(2.0, .lte, 4.0));
try expect(compareF80(-2.0, .gt, -4.0));
try expect(compareF80(-2.0, .gte, -4.0));
}
fn compareF80(x: f80, op: math.CompareOperator, y: f80) bool {
return math.compare(x, op, y);
}
// TODO This is waiting on library support for the Windows build (not sure why the other's don't need it)
//test "@nearbyint" {
// comptime testNearbyInt();