From 6316129e066e0a252430699f2b41706d4808476c Mon Sep 17 00:00:00 2001 From: Mehdi Amini Date: Thu, 17 Mar 2022 22:19:33 +0000 Subject: [PATCH] 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 --- llvm/CMakeLists.txt | 1 + llvm/docs/CMake.rst | 6 ++++++ llvm/include/llvm/Config/llvm-config.h.cmake | 4 ++++ llvm/include/llvm/Support/ErrorHandling.h | 14 +++++++++++--- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index 9892c6c..988c77b6 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -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) diff --git a/llvm/docs/CMake.rst b/llvm/docs/CMake.rst index ac635fc..4f5a0bb 100644 --- a/llvm/docs/CMake.rst +++ b/llvm/docs/CMake.rst @@ -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 diff --git a/llvm/include/llvm/Config/llvm-config.h.cmake b/llvm/include/llvm/Config/llvm-config.h.cmake index d8edf33..f8281d8 100644 --- a/llvm/include/llvm/Config/llvm-config.h.cmake +++ b/llvm/include/llvm/Config/llvm-config.h.cmake @@ -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 diff --git a/llvm/include/llvm/Support/ErrorHandling.h b/llvm/include/llvm/Support/ErrorHandling.h index f980510..8d51836 100644 --- a/llvm/include/llvm/Support/ErrorHandling.h +++ b/llvm/include/llvm/Support/ErrorHandling.h @@ -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 -- 2.7.4