compiler-rt: math functions reorg

* unify the logic for exporting math functions from compiler-rt,
   with the appropriate suffixes and prefixes.
   - add all missing f128 and f80 exports. Functions with missing
     implementations call other functions and have TODO comments.
   - also add f16 functions
 * move math functions from freestanding libc to compiler-rt (#7265)
 * enable all the f128 and f80 code in the stage2 compiler and behavior
   tests (#11161).
 * update std lib to use builtins rather than `std.math`.
This commit is contained in:
Andrew Kelley
2022-04-26 10:13:55 -07:00
parent 6f4343b61a
commit 41dd2beaac
66 changed files with 2617 additions and 2869 deletions

View File

@@ -6,6 +6,7 @@ const expectEqualSlices = std.testing.expectEqualSlices;
const maxInt = std.math.maxInt;
const minInt = std.math.minInt;
const mem = std.mem;
const math = std.math;
test "assignment operators" {
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
@@ -947,13 +948,13 @@ fn frem(comptime T: type) !void {
else => unreachable,
};
try expect(std.math.fabs(@rem(@as(T, 6.9), @as(T, 4.0)) - @as(T, 2.9)) < epsilon);
try expect(std.math.fabs(@rem(@as(T, -6.9), @as(T, 4.0)) - @as(T, -2.9)) < epsilon);
try expect(std.math.fabs(@rem(@as(T, -5.0), @as(T, 3.0)) - @as(T, -2.0)) < epsilon);
try expect(std.math.fabs(@rem(@as(T, 3.0), @as(T, 2.0)) - @as(T, 1.0)) < epsilon);
try expect(std.math.fabs(@rem(@as(T, 1.0), @as(T, 2.0)) - @as(T, 1.0)) < epsilon);
try expect(std.math.fabs(@rem(@as(T, 0.0), @as(T, 1.0)) - @as(T, 0.0)) < epsilon);
try expect(std.math.fabs(@rem(@as(T, -0.0), @as(T, 1.0)) - @as(T, -0.0)) < epsilon);
try expect(@fabs(@rem(@as(T, 6.9), @as(T, 4.0)) - @as(T, 2.9)) < epsilon);
try expect(@fabs(@rem(@as(T, -6.9), @as(T, 4.0)) - @as(T, -2.9)) < epsilon);
try expect(@fabs(@rem(@as(T, -5.0), @as(T, 3.0)) - @as(T, -2.0)) < epsilon);
try expect(@fabs(@rem(@as(T, 3.0), @as(T, 2.0)) - @as(T, 1.0)) < epsilon);
try expect(@fabs(@rem(@as(T, 1.0), @as(T, 2.0)) - @as(T, 1.0)) < epsilon);
try expect(@fabs(@rem(@as(T, 0.0), @as(T, 1.0)) - @as(T, 0.0)) < epsilon);
try expect(@fabs(@rem(@as(T, -0.0), @as(T, 1.0)) - @as(T, -0.0)) < epsilon);
}
test "float modulo division using @mod" {
@@ -978,13 +979,13 @@ fn fmod(comptime T: type) !void {
else => unreachable,
};
try expect(std.math.fabs(@mod(@as(T, 6.9), @as(T, 4.0)) - @as(T, 2.9)) < epsilon);
try expect(std.math.fabs(@mod(@as(T, -6.9), @as(T, 4.0)) - @as(T, 1.1)) < epsilon);
try expect(std.math.fabs(@mod(@as(T, -5.0), @as(T, 3.0)) - @as(T, 1.0)) < epsilon);
try expect(std.math.fabs(@mod(@as(T, 3.0), @as(T, 2.0)) - @as(T, 1.0)) < epsilon);
try expect(std.math.fabs(@mod(@as(T, 1.0), @as(T, 2.0)) - @as(T, 1.0)) < epsilon);
try expect(std.math.fabs(@mod(@as(T, 0.0), @as(T, 1.0)) - @as(T, 0.0)) < epsilon);
try expect(std.math.fabs(@mod(@as(T, -0.0), @as(T, 1.0)) - @as(T, -0.0)) < epsilon);
try expect(@fabs(@mod(@as(T, 6.9), @as(T, 4.0)) - @as(T, 2.9)) < epsilon);
try expect(@fabs(@mod(@as(T, -6.9), @as(T, 4.0)) - @as(T, 1.1)) < epsilon);
try expect(@fabs(@mod(@as(T, -5.0), @as(T, 3.0)) - @as(T, 1.0)) < epsilon);
try expect(@fabs(@mod(@as(T, 3.0), @as(T, 2.0)) - @as(T, 1.0)) < epsilon);
try expect(@fabs(@mod(@as(T, 1.0), @as(T, 2.0)) - @as(T, 1.0)) < epsilon);
try expect(@fabs(@mod(@as(T, 0.0), @as(T, 1.0)) - @as(T, 0.0)) < epsilon);
try expect(@fabs(@mod(@as(T, -0.0), @as(T, 1.0)) - @as(T, -0.0)) < epsilon);
}
test "@sqrt" {
@@ -1288,8 +1289,8 @@ test "NaN comparison f80" {
}
fn testNanEqNan(comptime F: type) !void {
var nan1 = std.math.nan(F);
var nan2 = std.math.nan(F);
var nan1 = math.nan(F);
var nan2 = math.nan(F);
try expect(nan1 != nan2);
try expect(!(nan1 == nan2));
try expect(!(nan1 > nan2));
@@ -1346,3 +1347,40 @@ test "signed zeros are represented properly" {
try S.doTheTest();
comptime try S.doTheTest();
}
test "comptime sin and ln" {
const v = comptime (@sin(@as(f32, 1)) + @log(@as(f32, 5)));
try expect(v == @sin(@as(f32, 1)) + @log(@as(f32, 5)));
}
test "fabs" {
inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| {
// normals
try expect(@fabs(@as(T, 1.0)) == 1.0);
try expect(@fabs(@as(T, -1.0)) == 1.0);
try expect(@fabs(math.floatMin(T)) == math.floatMin(T));
try expect(@fabs(-math.floatMin(T)) == math.floatMin(T));
try expect(@fabs(math.floatMax(T)) == math.floatMax(T));
try expect(@fabs(-math.floatMax(T)) == math.floatMax(T));
// subnormals
try expect(@fabs(@as(T, 0.0)) == 0.0);
try expect(@fabs(@as(T, -0.0)) == 0.0);
try expect(@fabs(math.floatTrueMin(T)) == math.floatTrueMin(T));
try expect(@fabs(-math.floatTrueMin(T)) == math.floatTrueMin(T));
// non-finite numbers
try expect(math.isPositiveInf(@fabs(math.inf(T))));
try expect(math.isPositiveInf(@fabs(-math.inf(T))));
try expect(math.isNan(@fabs(math.nan(T))));
}
}
test "absFloat" {
try testAbsFloat();
comptime try testAbsFloat();
}
fn testAbsFloat() !void {
try expect(@fabs(@as(f32, -10.05)) == @as(f32, 10.05));
try expect(@fabs(@as(f32, 10.05)) == @as(f32, 10.05));
}