Add a cmake flag to turn llvm_unreachable() into builtin_trap() when assertions are disabled

Reviewed By: dexonsmith

Differential Revision: https://reviews.llvm.org/D121750
This commit is contained in:
Mehdi Amini
2022-03-17 22:19:33 +00:00
parent 74b45f91b8
commit 6316129e06
4 changed files with 22 additions and 3 deletions

View File

@@ -465,6 +465,7 @@ option(LLVM_ENABLE_PEDANTIC "Compile with pedantic enabled." ON)
option(LLVM_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)
option(LLVM_ENABLE_DUMP "Enable dump functions even when assertions are disabled" OFF)
option(LLVM_UNREACHABLE_OPTIMIZE "Optimize llvm_unreachable() as undefined behavior (default), guaranteed trap when OFF" ON)
if( NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" )
option(LLVM_ENABLE_ASSERTIONS "Enable assertions" OFF)

View File

@@ -300,6 +300,12 @@ enabled sub-projects. Nearly all of these variable names begin with
enabled or not. A version of LLVM built with ABI breaking checks
is not ABI compatible with a version built without it.
**LLVM_UNREACHABLE_OPTIMIZE**:BOOL
This flag controls the behavior of `llvm_unreachable()` in release build
(when assertions are disabled in general). When ON (default) then
`llvm_unreachable()` is considered "undefined behavior" and optimized as
such. When OFF it is instead replaced with a guaranteed "trap".
**LLVM_APPEND_VC_REV**:BOOL
Embed version control revision info (Git revision id).
The version info is provided by the ``LLVM_REVISION`` macro in

View File

@@ -112,4 +112,8 @@
/* Define if building LLVM with LLVM_FORCE_USE_OLD_TOOLCHAIN_LIBS */
#cmakedefine LLVM_FORCE_USE_OLD_TOOLCHAIN ${LLVM_FORCE_USE_OLD_TOOLCHAIN}
/* Define if llvm_unreachable should be optimized with undefined behavior
* in non assert builds */
#cmakedefine01 LLVM_UNREACHABLE_OPTIMIZE
#endif

View File

@@ -124,15 +124,23 @@ llvm_unreachable_internal(const char *msg = nullptr, const char *file = nullptr,
/// Marks that the current location is not supposed to be reachable.
/// In !NDEBUG builds, prints the message and location info to stderr.
/// In NDEBUG builds, becomes an optimizer hint that the current location
/// is not supposed to be reachable. On compilers that don't support
/// such hints, prints a reduced message instead and aborts the program.
/// In NDEBUG builds, the behavior is controlled by the CMake flag
/// -DLLVM_UNREACHABLE_OPTIMIZE
/// * When "ON" (default) llvm_unreachable() becomes an optimizer hint
/// that the current location is not supposed to be reachable: the hint
/// turns such code path into undefined behavior. On compilers that don't
/// support such hints, prints a reduced message instead and aborts the
/// program.
/// * When "OFF", a builtin_trap is emitted instead of an
// optimizer hint or printing a reduced message.
///
/// Use this instead of assert(0). It conveys intent more clearly and
/// allows compilers to omit some unnecessary code.
#ifndef NDEBUG
#define llvm_unreachable(msg) \
::llvm::llvm_unreachable_internal(msg, __FILE__, __LINE__)
#elif LLVM_UNREACHABLE_OPTIMIZE
#define llvm_unreachable(msg) LLVM_BUILTIN_TRAP
#elif defined(LLVM_BUILTIN_UNREACHABLE)
#define llvm_unreachable(msg) LLVM_BUILTIN_UNREACHABLE
#else