authorgravatar for carl@astholm.seCarl Åstholm <carl@astholm.se> 2023-08-20 23:47:06+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-08-21 11:26:25-07:00
log60fc18bd1c154f3c728a147c4574b5db8a17f08e
treeb5cbc46487b23e553715aba706e85cedb7c7eef5
parentf74e10cd4722512ac671f574b3d274ab48abb1a7

compiler_rt: fix f80 comparisons

This corrects comparisons between negative numbers.

2 files changed, 34 insertions(+), 1 deletions(-)

lib/compiler_rt/comparef.zig+12-1
...@@ -89,7 +89,7 @@ pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT {...@@ -89,7 +89,7 @@ pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT {
89 } else {89 } else {
90 const a_fraction = a_rep.fraction | (@as(u80, a_rep.exp) << sig_bits);90 const a_fraction = a_rep.fraction | (@as(u80, a_rep.exp) << sig_bits);
91 const b_fraction = b_rep.fraction | (@as(u80, b_rep.exp) << sig_bits);91 const b_fraction = b_rep.fraction | (@as(u80, b_rep.exp) << sig_bits);
92 if (a_fraction < b_fraction) {92 if ((a_fraction < b_fraction) == (a_rep.exp & sign_bit == 0)) {
93 return .Less;93 return .Less;
94 } else {94 } else {
95 return .Greater;95 return .Greater;
...@@ -97,6 +97,17 @@ pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT {...@@ -97,6 +97,17 @@ pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT {
97 }97 }
98}98}
9999
100test "cmp_f80" {
101 inline for (.{ LE, GE }) |RT| {
102 try std.testing.expect(cmp_f80(RT, 1.0, 1.0) == RT.Equal);
103 try std.testing.expect(cmp_f80(RT, 0.0, -0.0) == RT.Equal);
104 try std.testing.expect(cmp_f80(RT, 2.0, 4.0) == RT.Less);
105 try std.testing.expect(cmp_f80(RT, 2.0, -4.0) == RT.Greater);
106 try std.testing.expect(cmp_f80(RT, -2.0, -4.0) == RT.Greater);
107 try std.testing.expect(cmp_f80(RT, -2.0, 4.0) == RT.Less);
108 }
109}
110
100pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 {111pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 {
101 const rep_t = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);112 const rep_t = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
102113
test/behavior/floatop.zig+22
...@@ -70,6 +70,28 @@ fn testDifferentSizedFloatComparisons() !void {...@@ -70,6 +70,28 @@ fn testDifferentSizedFloatComparisons() !void {
70 try expect(a < b);70 try expect(a < b);
71}71}
7272
73test "f80 comparisons" {
74 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
75 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
76 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
77 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
78 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
79 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
80
81 try expect(compareF80(0.0, .eq, -0.0));
82 try expect(compareF80(0.0, .lte, -0.0));
83 try expect(compareF80(0.0, .gte, -0.0));
84 try expect(compareF80(1.0, .neq, -1.0));
85 try expect(compareF80(2.0, .lt, 4.0));
86 try expect(compareF80(2.0, .lte, 4.0));
87 try expect(compareF80(-2.0, .gt, -4.0));
88 try expect(compareF80(-2.0, .gte, -4.0));
89}
90
91fn compareF80(x: f80, op: math.CompareOperator, y: f80) bool {
92 return math.compare(x, op, y);
93}
94
73// TODO This is waiting on library support for the Windows build (not sure why the other's don't need it)95// TODO This is waiting on library support for the Windows build (not sure why the other's don't need it)
74//test "@nearbyint" {96//test "@nearbyint" {
75// comptime testNearbyInt();97// comptime testNearbyInt();