Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ function(_get_compile_options_from_config output_var)
list(APPEND config_options "-DLIBC_THREAD_MODE=${LIBC_CONF_THREAD_MODE}")
endif()

if(LIBC_CONF_TRAP_ON_RAISE_FP_EXCEPT)
list(APPEND config_options "-DLIBC_TRAP_ON_RAISE_FP_EXCEPT")
endif()

set(${output_var} ${config_options} PARENT_SCOPE)
endfunction(_get_compile_options_from_config)

Expand Down
6 changes: 6 additions & 0 deletions libc/config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,5 +130,11 @@
"value": true,
"doc": "Add nullptr checks in the library's implementations to some functions for which passing nullptr is undefined behavior."
}
},
"fenv": {
"LIBC_CONF_TRAP_ON_RAISE_FP_EXCEPT": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be on by default?

"value": false,
"doc": "Trap with SIGFPE when feraiseexcept is called with unmasked floating point exceptions, similar to glibc's behavior. This is currently working only on x86 with SSE."
}
}
}
2 changes: 2 additions & 0 deletions libc/docs/configure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ to learn about the defaults for your platform and target.
- ``LIBC_CONF_KEEP_FRAME_POINTER``: Keep frame pointer in functions for better debugging experience.
* **"errno" options**
- ``LIBC_CONF_ERRNO_MODE``: The implementation used for errno, acceptable values are LIBC_ERRNO_MODE_DEFAULT, LIBC_ERRNO_MODE_UNDEFINED, LIBC_ERRNO_MODE_THREAD_LOCAL, LIBC_ERRNO_MODE_SHARED, LIBC_ERRNO_MODE_EXTERNAL, and LIBC_ERRNO_MODE_SYSTEM_INLINE.
* **"fenv" options**
- ``LIBC_CONF_TRAP_ON_RAISE_FP_EXCEPT``: Trap with SIGFPE when feraiseexcept is called with unmasked floating point exceptions, similar to glibc's behavior. This is currently working only on x86 with SSE.
* **"general" options**
- ``LIBC_ADD_NULL_CHECKS``: Add nullptr checks in the library's implementations to some functions for which passing nullptr is undefined behavior.
* **"math" options**
Expand Down
5 changes: 3 additions & 2 deletions libc/include/llvm-libc-macros/fenv-macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
#define FE_INVALID 0x4
#define FE_OVERFLOW 0x8
#define FE_UNDERFLOW 0x10
#define __FE_DENORM 0x20
#define FE_DENORM 0x20
#define FE_ALL_EXCEPT \
(FE_DIVBYZERO | FE_INEXACT | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
(FE_DIVBYZERO | FE_INEXACT | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW | \
FE_DENORM)

#define FE_DOWNWARD 0x400
#define FE_TONEAREST 0
Expand Down
36 changes: 30 additions & 6 deletions libc/src/__support/CPP/bit.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ namespace cpp {
#define LLVM_LIBC_HAS_BUILTIN_MEMCPY_INLINE
#endif

template <unsigned N>
LIBC_INLINE static void inline_copy(const char *from, char *to) {
#if __has_builtin(__builtin_memcpy_inline)
__builtin_memcpy_inline(to, from, N);
#else
for (unsigned i = 0; i < N; ++i)
to[i] = from[i];
#endif // __has_builtin(__builtin_memcpy_inline)
}

// This implementation of bit_cast requires trivially-constructible To, to avoid
// UB in the implementation.
template <typename To, typename From>
Expand All @@ -43,16 +53,30 @@ bit_cast(const From &from) {
To to{};
char *dst = reinterpret_cast<char *>(&to);
const char *src = reinterpret_cast<const char *>(&from);
#if __has_builtin(__builtin_memcpy_inline)
__builtin_memcpy_inline(dst, src, sizeof(To));
#else
for (unsigned i = 0; i < sizeof(To); ++i)
dst[i] = src[i];
#endif // __has_builtin(__builtin_memcpy_inline)
inline_copy<sizeof(From)>(src, dst);
return to;
#endif // __has_builtin(__builtin_bit_cast)
}

// The following simple bit copy from a smaller type to maybe-larger type.
template <typename To, typename From>
LIBC_INLINE constexpr cpp::enable_if_t<
(sizeof(To) >= sizeof(From)) &&
cpp::is_trivially_constructible<To>::value &&
cpp::is_trivially_copyable<To>::value &&
cpp::is_trivially_copyable<From>::value,
void>
bit_copy(const From &from, To &to) {
MSAN_UNPOISON(&from, sizeof(From));
if constexpr (sizeof(To) == sizeof(From)) {
to = bit_cast<To>(from);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This case calls To::operator=, which seems inconsistent with the name "bit_copy" and the else clause.

} else {
char *dst = reinterpret_cast<char *>(&to);
const char *src = reinterpret_cast<const char *>(&from);
inline_copy<sizeof(From)>(src, dst);
}
}

template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>,
bool>
Expand Down
1 change: 1 addition & 0 deletions libc/src/__support/FPUtil/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ add_header_library(
libc.hdr.fenv_macros
libc.hdr.math_macros
libc.hdr.stdint_proxy
libc.src.__support.CPP.bit
libc.src.__support.CPP.type_traits
libc.src.__support.macros.attributes
libc.src.errno.errno
Expand Down
8 changes: 1 addition & 7 deletions libc/src/__support/FPUtil/FEnvImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@
// the dummy implementations below. Once a proper x86_64 darwin fenv is set up,
// the apple condition here should be removed.
// TODO: fully support fenv for MSVC.
#elif defined(LIBC_TARGET_ARCH_IS_X86) && !defined(__APPLE__) && \
!defined(LIBC_COMPILER_IS_MSVC)
#elif defined(LIBC_TARGET_ARCH_IS_X86) && !defined(__APPLE__)
#include "x86_64/FEnvImpl.h"
#elif defined(LIBC_TARGET_ARCH_IS_ARM) && defined(__ARM_FP) && \
!defined(LIBC_COMPILER_IS_MSVC)
Expand Down Expand Up @@ -110,12 +109,7 @@ raise_except_if_required([[maybe_unused]] int excepts) {
} else {
#ifndef LIBC_MATH_HAS_NO_EXCEPT
if (math_errhandling & MATH_ERREXCEPT)
#ifdef LIBC_TARGET_ARCH_IS_X86_64
return raise_except</*SKIP_X87_FPU*/ true>(excepts);
#else // !LIBC_TARGET_ARCH_IS_X86
return raise_except(excepts);
#endif // LIBC_TARGET_ARCH_IS_X86

#endif // LIBC_MATH_HAS_NO_EXCEPT
return 0;
}
Expand Down
Loading
Loading