Repository: llvm/llvm-project
File: libc/src/__support/math/asinpif.h (C/C++)

Code before:
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ASINPIF_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_ASINPIF_H

#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
#include "src/__support/FPUtil/cast.h"
#include "src/__support/FPUtil/multiply_add.h"
#include "src/__support/FPUtil/sqrt.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
#include "src/__support/macros/properties/types.h"

#include "hdr/errno_macros.h"
#include "hdr/fenv_macros.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/except_value_utils.h"

namespace LIBC_NAMESPACE_DECL {
namespace math {

LIBC_INLINE constexpr float asinpif(float x) {
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
  constexpr size_t N_EXCEPTS = 5;
  constexpr fputil::ExceptValues<float, N_EXCEPTS> ASINPIF_EXCEPTS = {
      {// (inputs, RZ output, RU offset, RD offset, RN offset)
       // x = 0x1.e768f6p-122, asinpif(x) = 0x1.364b7ap-123 (RZ)
       {0x02F3B47B, 0x021B25BD, 1, 0, 0},
       // x = 0x1.e768f6p-24, asinpif(x) = 0x1.364b7ap-25 (RZ)
       {0x33F3B47B, 0x331B25BD, 1, 0, 1},
       // x = 0x1.dddb4ep-19, asinpif(x) = 0x1.303686p-20 (RZ)
       {0x366EEDA7, 0x35981B43, 1, 0, 1},
       // x = -0x1.dddb4ep-19, asinpif(x) = -0x1.303686p-20 (RZ)
       {0xB66EEDA7, 0xB5981B43, 0, 1, 1},
       // x = -0x1.e768f6p-24, asinpif(x) = -0x1.364b7ap-25 (RZ)
       {0xB3F3B47B, 0xB31B25BD, 0, 1, 1}}};
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS

  using FPBits = fputil::FPBits<float>;

  FPBits xbits(x);
  bool is_neg = xbits.is_neg();
  double x_abs = fputil::cast<double>(xbits.abs().get_val());

  auto signed_result = [is_neg](auto r) -> auto { return is_neg ? -r : r; };

  if (LIBC_UNLIKELY(x_abs > 1.0)) {

Review comment (suggestion):
This function cannot be constexpr because of multiply_add
```suggestion
LIBC_INLINE float asinpif(float x) {
```

Code after:
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ASINPIF_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_ASINPIF_H

#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
#include "src/__support/FPUtil/cast.h"
#include "src/__support/FPUtil/except_value_utils.h"
#include "src/__support/FPUtil/multiply_add.h"
#include "src/__support/FPUtil/sqrt.h"
#include "src/__support/macros/optimization.h"

namespace LIBC_NAMESPACE_DECL {
namespace math {

LIBC_INLINE float asinpif(float x) {
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
  constexpr size_t N_EXCEPTS = 5;
  constexpr fputil::ExceptValues<float, N_EXCEPTS> ASINPIF_EXCEPTS = {
      {// (inputs, RZ output, RU offset, RD offset, RN offset)
       // x = 0x1.e768f6p-122, asinpif(x) = 0x1.364b7ap-123 (RZ)
       {0x02F3B47B, 0x021B25BD, 1, 0, 0},
       // x = 0x1.e768f6p-24, asinpif(x) = 0x1.364b7ap-25 (RZ)
       {0x33F3B47B, 0x331B25BD, 1, 0, 1},
       // x = 0x1.dddb4ep-19, asinpif(x) = 0x1.303686p-20 (RZ)
       {0x366EEDA7, 0x35981B43, 1, 0, 1},
       // x = -0x1.dddb4ep-19, asinpif(x) = -0x1.303686p-20 (RZ)
       {0xB66EEDA7, 0xB5981B43, 0, 1, 1},
       // x = -0x1.e768f6p-24, asinpif(x) = -0x1.364b7ap-25 (RZ)
       {0xB3F3B47B, 0xB31B25BD, 0, 1, 1}}};
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS

  using FPBits = fputil::FPBits<float>;

  FPBits xbits(x);
  bool is_neg = xbits.is_neg();
  double x_abs = fputil::cast<double>(xbits.abs().get_val());

  auto signed_result = [is_neg](auto r) -> auto { return is_neg ? -r : r; };

  if (LIBC_UNLIKELY(x_abs > 1.0)) {
    if (xbits.is_nan()) {
      if (xbits.is_signaling_nan()) {
        fputil::raise_except_if_required(FE_INVALID);
        return FPBits::quiet_nan().get_val();
      }