[llvm-branch-commits] [libc] 4726bec - [libc] Add implementation of fmaf.

2021-01-06 Thread Tue Ly via llvm-branch-commits

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.

2020-07-21 Thread Tue Ly via llvm-branch-commits

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.

2020-12-03 Thread Tue Ly via llvm-branch-commits

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