[libc-commits] [libc] [libc][math] Implement C23 half precision erfc function (PR #180930)
via libc-commits
libc-commits at lists.llvm.org
Thu Mar 12 20:59:10 PDT 2026
================
@@ -0,0 +1,196 @@
+//===-- Implementation header for erfcf16 -----------------------*- 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___SUPPORT_MATH_ERFCF16_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_ERFCF16_H
+
+#include "include/llvm-libc-macros/float16-macros.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+LIBC_INLINE float16 erfcf16(float16 x) {
+ // Polynomials approximating erfc(|x|) on ( k/8, (k + 1)/8 ) generated by
+ // Sollya with: > P = fpminimax(erfc(x), [|0, 1, 2, 3, 4, 5, 6, 7|], [|D...|],
+ // [k/8, (k + 1)/8]);
+ // for k = 0..31.
+ constexpr double COEFFS[32][8] = {
+ {0x1.000000000001ap0, -0x1.20dd75042fe11p0, 0x1.eedc6f1918987p-31,
+ 0x1.812743003751cp-2, 0x1.b64a20332eb3dp-20, -0x1.ce4a3020c5e8dp-4,
+ 0x1.c23deea13dadap-13, 0x1.ab4a28f5e2202p-6},
+ {0x1.000000261e1a9p0, -0x1.20dd7ba6be17dp0, 0x1.feaa7936695dep-18,
+ 0x1.8111aee222bb3p-2, 0x1.1e49370dc07e5p-11, -0x1.d7628d2f099dfp-4,
+ 0x1.64a9012704b63p-8, 0x1.507b7d761dbbdp-6},
+ {0x1.00000e7d6c906p0, -0x1.20deeb74e7ceep0, 0x1.06dc8c97aa061p-12,
+ 0x1.7f85253e7aa3fp-2, 0x1.9a4f9aedbda2ap-8, -0x1.06934bb956303p-3,
+ 0x1.6f9b296bf2cp-6, 0x1.6725f01ebef61p-7},
+ {0x1.0000f0d17e652p0, -0x1.20eec49f1bb9fp0, 0x1.15bf700a3afecp-9,
+ 0x1.7742179b9b76p-2, 0x1.bf4cf873dfcc7p-6, -0x1.4a7453b65895cp-3,
+ 0x1.a7171b2b94f65p-5, -0x1.3db6226bfb07ep-13},
+ {0x1.00064f5d99b02p0, -0x1.21388015af14dp0, 0x1.1f337b73afb37p-7,
+ 0x1.60d75bce880c8p-2, 0x1.21bee64bd2bfep-4, -0x1.b4c9b7cc4d861p-3,
+ 0x1.6156b46d67517p-4, -0x1.4a6ad4a1a9a6dp-7},
+ {0x1.001646fa41f93p0, -0x1.21ea485326f4dp0, 0x1.64386e40081f9p-6,
+ 0x1.3d6f1181dc1f2p-2, 0x1.025fb3fbb9694p-3, -0x1.111c22989270ep-2,
+ 0x1.d6df1d011e6a5p-4, -0x1.11af42f321738p-6},
+ {0x1.00277226071fep0, -0x1.228d8a26ceba9p0, 0x1.056317058c132p-5,
+ 0x1.25cda1a141e98p-2, 0x1.42d4218a6d87p-3, -0x1.2b8395261188dp-2,
+ 0x1.038075602477dp-3, -0x1.3754fc0d6d03dp-6},
+ {0x1.ffdf656fd5544p-1, -0x1.20dbf015167a4p0, 0x1.426f915ba02ccp-7,
+ 0x1.4fb39034f18e7p-2, 0x1.cb1896449b52p-4, -0x1.0c5791c048cfbp-2,
+ 0x1.d8acdd7692448p-4, -0x1.19cd761c2fcbfp-6},
+ {0x1.fd52aab04431fp-1, -0x1.18084cdb7869fp0, -0x1.7b239d67be2f2p-4,
+ 0x1.fce1bd937aa95p-2, -0x1.c7f53c1a8860cp-5, -0x1.4c0be3dd60746p-3,
+ 0x1.511a1822165ccp-4, -0x1.997b355ae9313p-7},
+ {0x1.f630da3ca180fp-1, -0x1.01f9cdebb8a42p0, -0x1.48d5e3d9e3bbbp-2,
+ 0x1.ab0c1d54fd42p-1, -0x1.6abcd4a981266p-2, -0x1.b62df36853d2ap-9,
+ 0x1.219207ea8070cp-5, -0x1.acb65c612c3cbp-8},
+ {0x1.e8518d1829bdep-1, -0x1.b680bb7f5ca05p-1, -0x1.5dd957f485f26p-1,
+ 0x1.50ed752c29101p0, -0x1.7a989bc66b636p-1, 0x1.73a7c29911c75p-3,
+ -0x1.c8f687bc29284p-7, -0x1.d9a2c5e81906dp-11},
+ {0x1.d455b8759924bp-1, -0x1.50d550bd0031ap-1, -0x1.1dd31217d772dp0,
+ 0x1.d768acdc964e1p0, -0x1.1f325385cfea3p0, 0x1.64f5ef1e1b149p-2,
+ -0x1.becf19e32832cp-5, 0x1.b3d95b8249dc2p-9},
+ {0x1.c03fc3d1dfd52p-1, -0x1.e5be0a5eb8ea1p-2, -0x1.7c0ea4743a94ap0,
+ 0x1.203ad2e0bb23dp1, -0x1.657e5f6a3a7bfp0, 0x1.d5e86ba1d05p-2,
+ -0x1.44444f5e3e2f1p-4, 0x1.7465b9882b39bp-8},
+ {0x1.b82e3874361f8p-1, -0x1.9f1c5ba9f25b5p-2, -0x1.9d2f419b75126p0,
+ 0x1.317ed738c38e5p1, -0x1.7b17d3b23fc5cp0, 0x1.f656370d9a5a4p-2,
+ -0x1.5f519dd3bee19p-4, 0x1.9b165d0ccb0fep-8},
+ {0x1.cba592d21041ap-1, -0x1.1c9e2f4ac28efp-1, -0x1.5bcbe8415d66fp0,
+ 0x1.12aa2de5d021cp1, -0x1.58324c5f23234p0, 0x1.c6ed4ac6a2edfp-2,
+ -0x1.3b86d3a3e85c9p-4, 0x1.6cc0ec77d11b9p-8},
+ {0x1.03caf33285512p0, -0x1.fb887e48a3eedp-1, -0x1.5431e46bb9a3fp-1,
+ 0x1.87e44d6713845p0, -0x1.047b2b206c351p0, 0x1.5c0fe8541e1e5p-2,
+ -0x1.df700bfe6dee5p-5, 0x1.1089feecce9f6p-8},
+ {0x1.37baad7246b3cp0, -0x1.b333d66d61c0cp0, 0x1.9673eefbcd456p-2,
+ 0x1.4b8e581c9bd57p-1, -0x1.271a5001975b3p-1, 0x1.a9544c9bc6f69p-3,
+ -0x1.2b04fcf02cfe4p-5, 0x1.52f61b5bf2013p-9},
+ {0x1.7c8089dfc728fp0, -0x1.4aca78f669032p1, 0x1.a50b5166895f1p0,
+ -0x1.52bccda96d2ddp-2, -0x1.db1a7723e7021p-4, 0x1.3e221766f1413p-4,
+ -0x1.07c689c1529d4p-6, 0x1.3e28897c72f86p-10},
+ {0x1.c677ecd59f0c9p0, -0x1.bddee5876d025p1, 0x1.6c05470bf9855p1,
+ -0x1.3838ea389805p0, 0x1.1e0da063ba588p-2, -0x1.c8701de42abb8p-6,
+ -0x1.d505f665736f4p-12, 0x1.ca3e25ddd2f8ep-13},
+ {0x1.0346dd8ccf496p1, -0x1.0e36567843072p2, 0x1.e39ee1779480ap1,
+ -0x1.e05781af98971p0, 0x1.1cd860f207bc6p-1, -0x1.91471b20d7ea7p-4,
+ 0x1.3472b380bd896p-7, -0x1.8a32a1c029365p-12},
+ {0x1.175cf188a8137p1, -0x1.2a6aea014a1a7p2, 0x1.13c3894652ae3p2,
+ -0x1.1d97a2368998p1, 0x1.65c57ae4f9a2ep-1, -0x1.0ee6b7e8303e8p-3,
+ 0x1.cae7deaf84ca3p-7, -0x1.4f32ea2cd38e3p-11},
+ {0x1.1b0bf6d5ea90bp1, -0x1.2f6bcdbfd2bf8p2, 0x1.199682b413d76p2,
+ -0x1.251f9f5a8b0dap1, 0x1.7174a7ecafc0ep-1, -0x1.19c6a1d04557fp-3,
+ 0x1.e164b9a559bfdp-7, -0x1.6320142d50654p-11},
+ {0x1.0d8865040d536p1, -0x1.1e4d7b5aadcb3p2, 0x1.06ffcd830db2p2,
+ -0x1.0eb1633113f1fp1, 0x1.50f8dac72a8f9p-1, -0x1.fb183d2925a88p-4,
+ 0x1.aadfbeb9cff03p-7, -0x1.35fe3091fd72bp-11},
+ {0x1.e30746fa5c05ap0, -0x1.f8814cab9a532p1, 0x1.c70d7871e1e66p1,
+ -0x1.cb40d988d46f7p0, 0x1.17ea520e30ee5p-1, -0x1.9bf4656539b33p-4,
+ 0x1.52ba88a712da3p-7, -0x1.dff8c68511d54p-12},
+ {0x1.980594d76c9c6p0, -0x1.a1111fecc5d33p1, 0x1.6fac90467734ap1,
+ -0x1.6a38a8cadbc1dp0, 0x1.ae83820056a13p-2, -0x1.3489645378924p-4,
+ 0x1.eda542162eab4p-8, -0x1.53f0f5d191e15p-12},
+ {0x1.4593f0667381p0, -0x1.44c18f230e828p1, 0x1.17126063fa673p1,
+ -0x1.0bb8315d99e44p0, 0x1.358c4f8bf482ep-2, -0x1.af3eebe9cb455p-5,
+ 0x1.4f090acf146ep-8, -0x1.bfc7954478304p-13},
+ {0x1.ebcae3fdca674p-1, -0x1.dde1bcf5a5146p0, 0x1.8fb142f724b27p0,
+ -0x1.74e2bafe8789fp-1, 0x1.a2f67a40275d7p-3, -0x1.1b6406e10fca4p-5,
+ 0x1.ab4ed0d6da84fp-9, -0x1.14f03579c96fep-13},
+ {0x1.6038027133b66p-1, -0x1.4d18991ed6939p0, 0x1.0ef1d6fa80951p0,
+ -0x1.eb55a8112702cp-2, 0x1.0c19cb48e5a46p-3, -0x1.60151a50d69f3p-6,
+ 0x1.018b2a2cf7aa6p-9, -0x1.43bda617ae0e6p-14},
+ {0x1.df3b0de232601p-2, -0x1.b8e05100448c4p-1, 0x1.5ca6e2528e8d1p-1,
+ -0x1.332de46c2acb5p-2, 0x1.4595849385e42p-4, -0x1.9f152046c7178p-7,
+ 0x1.26a2e0a31e9fp-10, -0x1.67436e13d44ddp-15},
+ {0x1.3628cccb902e9p-2, -0x1.1587e442957f9p-1, 0x1.aabedffc2818p-2,
+ -0x1.6d5f4f24a94a1p-3, 0x1.782f957586c48p-5, -0x1.d1b4c8cd3d9ap-8,
+ 0x1.40e4007f68b4dp-11, -0x1.7bb3eac541f35p-16},
+ {0x1.7e774f23dd5d8p-3, -0x1.4ce552c93ab17p-2, 0x1.f1ba61425c57ap-3,
+ -0x1.9e391990469f7p-4, 0x1.9e6adf17223b9p-6, -0x1.f2601fc8d5f7ep-9,
+ 0x1.4d7f6c4dab8cap-12, -0x1.7f24e1a9c9b8ap-17},
+ {0x1.c0bbabb6ec859p-4, -0x1.7bf5902ff3dfcp-3, 0x1.143e24f2802a6p-3,
+ -0x1.bf08869d7e41p-5, 0x1.b2b78fe704f97p-7, -0x1.fc05ca0a46accp-10,
+ 0x1.4a472fc484f8ap-13, -0x1.7091cb146f95ap-18},
+ };
+
+ using FPBits = typename fputil::FPBits<float16>;
+ FPBits xbits(x);
+ uint16_t x_abs = xbits.abs().uintval();
+
+ // Special cases: NaN and Inf
+ if (LIBC_UNLIKELY(x_abs >= 0x7c00U)) {
+ if (x_abs > 0x7c00U) {
+ if (xbits.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+ return x;
+ }
+ // erfc(+Inf) = 0, erfc(-Inf) = 2
+ return xbits.is_neg() ? static_cast<float16>(2.0)
----------------
lntue wrote:
need `fputil::cast<float16>` instead of `static_cast` in this file.
https://github.com/llvm/llvm-project/pull/180930
More information about the libc-commits
mailing list