[llvm-branch-commits] [libc] 4726bec - [libc] Add implementation of fmaf.
Author: Tue Ly Date: 2021-01-06T17:14:20-05:00 New Revision: 4726bec8f29bd535e2709b491d223d42bd20c120 URL: https://github.com/llvm/llvm-project/commit/4726bec8f29bd535e2709b491d223d42bd20c120 DIFF: https://github.com/llvm/llvm-project/commit/4726bec8f29bd535e2709b491d223d42bd20c120.diff LOG: [libc] Add implementation of fmaf. Differential Revision: https://reviews.llvm.org/D94018 Added: libc/src/math/fmaf.cpp libc/src/math/fmaf.h libc/test/src/math/FmaTest.h libc/test/src/math/fmaf_test.cpp Modified: libc/config/linux/aarch64/entrypoints.txt libc/config/linux/x86_64/entrypoints.txt libc/spec/stdc.td libc/src/math/CMakeLists.txt libc/test/src/math/CMakeLists.txt libc/utils/FPUtil/FPBits.h libc/utils/MPFRWrapper/MPFRUtils.cpp libc/utils/MPFRWrapper/MPFRUtils.h Removed: diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index b9042625e666..0db8c4b39caa 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -65,6 +65,7 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.math.floor libc.src.math.floorf libc.src.math.floorl +libc.src.math.fmaf libc.src.math.fmax libc.src.math.fmaxf libc.src.math.fmaxl diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index a34c59646149..a80a8b4f105b 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -106,6 +106,7 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.math.floor libc.src.math.floorf libc.src.math.floorl +libc.src.math.fmaf libc.src.math.fmin libc.src.math.fminf libc.src.math.fminl diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td index 41f6083a2336..e89d16633ae3 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -322,6 +322,8 @@ def StdC : StandardSpec<"stdc"> { FunctionSpec<"fmaxf", RetValSpec, [ArgSpec, ArgSpec]>, FunctionSpec<"fmaxl", RetValSpec, [ArgSpec, ArgSpec]>, + FunctionSpec<"fmaf", RetValSpec, [ArgSpec, ArgSpec, ArgSpec]>, + FunctionSpec<"frexp", RetValSpec, [ArgSpec, ArgSpec]>, FunctionSpec<"frexpf", RetValSpec, [ArgSpec, ArgSpec]>, FunctionSpec<"frexpl", RetValSpec, [ArgSpec, ArgSpec]>, diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt index 15a2e4645edd..34b7dfcd4306 100644 --- a/libc/src/math/CMakeLists.txt +++ b/libc/src/math/CMakeLists.txt @@ -978,3 +978,14 @@ add_entrypoint_object( -O2 ) +add_entrypoint_object( + fmaf + SRCS +fmaf.cpp + HDRS +fmaf.h + DEPENDS +libc.utils.FPUtil.fputil + COMPILE_OPTIONS +-O2 +) diff --git a/libc/src/math/fmaf.cpp b/libc/src/math/fmaf.cpp new file mode 100644 index ..1860d887d630 --- /dev/null +++ b/libc/src/math/fmaf.cpp @@ -0,0 +1,64 @@ +//===-- Implementation of fmaf function ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "src/__support/common.h" + +#include "utils/FPUtil/FEnv.h" +#include "utils/FPUtil/FPBits.h" + +namespace __llvm_libc { + +float LLVM_LIBC_ENTRYPOINT(fmaf)(float x, float y, float z) { + // Product is exact. + double prod = static_cast(x) * static_cast(y); + double z_d = static_cast(z); + double sum = prod + z_d; + fputil::FPBits bit_prod(prod), bitz(z_d), bit_sum(sum); + + if (!(bit_sum.isInfOrNaN() || bit_sum.isZero())) { +// Since the sum is computed in double precision, rounding might happen +// (for instance, when bitz.exponent > bit_prod.exponent + 5, or +// bit_prod.exponent > bitz.exponent + 40). In that case, when we round +// the sum back to float, double rounding error might occur. +// A concrete example of this phenomenon is as follows: +// x = y = 1 + 2^(-12), z = 2^(-53) +// The exact value of x*y + z is 1 + 2^(-11) + 2^(-24) + 2^(-53) +// So when rounding to float, fmaf(x, y, z) = 1 + 2^(-11) + 2^(-23) +// On the other hand, with the default rounding mode, +// double(x*y + z) = 1 + 2^(-11) + 2^(-24) +// and casting again to float gives us: +// float(double(x*y + z)) = 1 + 2^(-11). +// +// In order to correct this possible double rounding error, first we use +// Dekker's 2Sum algorithm to find t such that sum - t = prod + z exactly, +// assuming the (default) rounding mode is round-to-the-nearest, +// tie-to-even. Moreover, t satisfies the condition that t < eps(sum), +// i.e., t.exponent < sum.exponent - 52. So if t is not 0, meaning rounding +// occurs when com
[llvm-branch-commits] [libc] 34f66c1 - Add implementations for fmin, fminf, and fminl. Testing infrastructure update is splitted to https://reviews.llvm.org/D83931.
Author: Tue Ly Date: 2020-07-21T16:55:32-04:00 New Revision: 34f66c1438efce5184c030cbfd41f9e5164b1523 URL: https://github.com/llvm/llvm-project/commit/34f66c1438efce5184c030cbfd41f9e5164b1523 DIFF: https://github.com/llvm/llvm-project/commit/34f66c1438efce5184c030cbfd41f9e5164b1523.diff LOG: Add implementations for fmin, fminf, and fminl. Testing infrastructure update is splitted to https://reviews.llvm.org/D83931. Added: libc/src/math/fmin.cpp libc/src/math/fmin.h libc/src/math/fminf.cpp libc/src/math/fminf.h libc/src/math/fminl.cpp libc/src/math/fminl.h libc/test/src/math/fmin_test.cpp libc/test/src/math/fminf_test.cpp libc/test/src/math/fminl_test.cpp Modified: libc/config/linux/aarch64/entrypoints.txt libc/config/linux/api.td libc/config/linux/x86_64/entrypoints.txt libc/spec/stdc.td libc/src/math/CMakeLists.txt libc/test/src/math/CMakeLists.txt libc/utils/FPUtil/BasicOperations.h libc/utils/FPUtil/CMakeLists.txt Removed: diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index 592d142ca6c4..cd805d7b8653 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -31,6 +31,9 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.math.floor libc.src.math.floorf libc.src.math.floorl +libc.src.math.fmin +libc.src.math.fminf +libc.src.math.fminl libc.src.math.frexp libc.src.math.frexpf libc.src.math.frexpl diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td index 9b9ed1b49298..22e97b891a75 100644 --- a/libc/config/linux/api.td +++ b/libc/config/linux/api.td @@ -163,6 +163,9 @@ def MathAPI : PublicAPI<"math.h"> { "floor", "floorf", "floorl", + "fmin", + "fminf", + "fminl", "frexp", "frexpf", "frexpl", diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index f08f775cd892..e8a1adbb278e 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -64,6 +64,9 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.math.floor libc.src.math.floorf libc.src.math.floorl +libc.src.math.fmin +libc.src.math.fminf +libc.src.math.fminl libc.src.math.frexp libc.src.math.frexpf libc.src.math.frexpl diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td index 2af79373c30c..cdeee89be507 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -205,6 +205,10 @@ def StdC : StandardSpec<"stdc"> { FunctionSpec<"floorf", RetValSpec, [ArgSpec]>, FunctionSpec<"floorl", RetValSpec, [ArgSpec]>, + FunctionSpec<"fmin", RetValSpec, [ArgSpec, ArgSpec]>, + FunctionSpec<"fminf", RetValSpec, [ArgSpec, ArgSpec]>, + FunctionSpec<"fminl", RetValSpec, [ArgSpec, ArgSpec]>, + FunctionSpec<"frexp", RetValSpec, [ArgSpec, ArgSpec]>, FunctionSpec<"frexpf", RetValSpec, [ArgSpec, ArgSpec]>, FunctionSpec<"frexpl", RetValSpec, [ArgSpec, ArgSpec]>, diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt index aa8680383b7a..d2d694807168 100644 --- a/libc/src/math/CMakeLists.txt +++ b/libc/src/math/CMakeLists.txt @@ -413,3 +413,39 @@ add_entrypoint_object( COMPILE_OPTIONS -O2 ) + +add_entrypoint_object( + fmin + SRCS +fmin.cpp + HDRS +fmin.h + DEPENDS +libc.utils.FPUtil.fputil + COMPILE_OPTIONS +-O2 +) + +add_entrypoint_object( + fminf + SRCS +fminf.cpp + HDRS +fminf.h + DEPENDS +libc.utils.FPUtil.fputil + COMPILE_OPTIONS +-O2 +) + +add_entrypoint_object( + fminl + SRCS +fminl.cpp + HDRS +fminl.h + DEPENDS +libc.utils.FPUtil.fputil + COMPILE_OPTIONS +-O2 +) diff --git a/libc/src/math/fmin.cpp b/libc/src/math/fmin.cpp new file mode 100644 index ..ef5efad59811 --- /dev/null +++ b/libc/src/math/fmin.cpp @@ -0,0 +1,18 @@ +//===-- Implementation of fmin function ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "src/__support/common.h" +#include "utils/FPUtil/BasicOperations.h" + +namespace __llvm_libc { + +double LLVM_LIBC_ENTRYPOINT(fmin)(double x, double y) { + return fputil::fmin(x, y); +} + +} // namespace __llvm_libc diff --git a/libc/src/math/fmin.h b/libc/src/math/fmin.h new file mode 100644 index ..52334ee8e456 --- /dev/null +++ b/libc/src/math/fmin.h @@ -0,0 +1,18 @@ +//===-- Implementation header for fmin --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License
[llvm-branch-commits] [libc] 3b487d5 - [libc] Add implementation of hypot.
Author: Tue Ly Date: 2020-12-03T11:08:20-05:00 New Revision: 3b487d51e2ec699c27387fc30374f0d035b2a482 URL: https://github.com/llvm/llvm-project/commit/3b487d51e2ec699c27387fc30374f0d035b2a482 DIFF: https://github.com/llvm/llvm-project/commit/3b487d51e2ec699c27387fc30374f0d035b2a482.diff LOG: [libc] Add implementation of hypot. Refactor src/math/hypotf.cpp and test/src/math/hypotf_test.cpp and reuse them for hypot and hypot_test Differential Revision: https://reviews.llvm.org/D91831 Added: libc/src/math/hypot.cpp libc/src/math/hypot.h libc/test/src/math/HypotTest.h libc/test/src/math/hypot_test.cpp libc/utils/FPUtil/Hypot.h Modified: libc/config/linux/aarch64/entrypoints.txt libc/config/linux/x86_64/entrypoints.txt libc/spec/stdc.td libc/src/math/CMakeLists.txt libc/src/math/hypotf.cpp libc/test/src/math/CMakeLists.txt libc/test/src/math/hypotf_test.cpp Removed: diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index 1d8e5dd83672..3a3b050a6e06 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -68,6 +68,7 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.math.frexp libc.src.math.frexpf libc.src.math.frexpl +libc.src.math.hypot libc.src.math.hypotf libc.src.math.ilogb libc.src.math.ilogbf diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index d6d56f2e33a5..7401715058ac 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -104,6 +104,7 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.math.frexp libc.src.math.frexpf libc.src.math.frexpl +libc.src.math.hypot libc.src.math.hypotf libc.src.math.ilogb libc.src.math.ilogbf diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td index 7275f1e0aacf..d40fe8df3942 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -280,6 +280,7 @@ def StdC : StandardSpec<"stdc"> { FunctionSpec<"frexpf", RetValSpec, [ArgSpec, ArgSpec]>, FunctionSpec<"frexpl", RetValSpec, [ArgSpec, ArgSpec]>, + FunctionSpec<"hypot", RetValSpec, [ArgSpec, ArgSpec]>, FunctionSpec<"hypotf", RetValSpec, [ArgSpec, ArgSpec]>, FunctionSpec<"ilogb", RetValSpec, [ArgSpec]>, diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt index fd75a3b48bcb..8201d737ddb1 100644 --- a/libc/src/math/CMakeLists.txt +++ b/libc/src/math/CMakeLists.txt @@ -713,3 +713,15 @@ add_entrypoint_object( COMPILE_OPTIONS -O2 ) + +add_entrypoint_object( + hypot + SRCS +hypot.cpp + HDRS +hypot.h + DEPENDS +libc.utils.FPUtil.fputil + COMPILE_OPTIONS +-O2 +) diff --git a/libc/src/math/hypot.cpp b/libc/src/math/hypot.cpp new file mode 100644 index ..9d59365ce3f2 --- /dev/null +++ b/libc/src/math/hypot.cpp @@ -0,0 +1,18 @@ +//===-- Implementation of hypot function --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "utils/FPUtil/Hypot.h" +#include "src/__support/common.h" + +namespace __llvm_libc { + +double LLVM_LIBC_ENTRYPOINT(hypot)(double x, double y) { + return __llvm_libc::fputil::hypot(x, y); +} + +} // namespace __llvm_libc diff --git a/libc/src/math/hypot.h b/libc/src/math/hypot.h new file mode 100644 index ..6c901ee8f4c0 --- /dev/null +++ b/libc/src/math/hypot.h @@ -0,0 +1,18 @@ +//===-- Implementation header for hypot -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef LLVM_LIBC_SRC_MATH_HYPOT_H +#define LLVM_LIBC_SRC_MATH_HYPOT_H + +namespace __llvm_libc { + +double hypot(double x, double y); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_MATH_HYPOT_H diff --git a/libc/src/math/hypotf.cpp b/libc/src/math/hypotf.cpp index 10ebbb1b9ec9..ebe7e97ee184 100644 --- a/libc/src/math/hypotf.cpp +++ b/libc/src/math/hypotf.cpp @@ -6,217 +6,12 @@ // //===--===// #include "src/__support/common.h" -#include "utils/FPUtil/BasicOperations.h" -#include "utils/FPUtil/FPBits.h" +#include "utils/FPUtil/Hypot.h" namespace __llvm_libc { -using namespace fputil; - -uint32_t findLeadingOne(uint32_t mant, int &shift_length) { - shift_length = 0; - c