From 3b119539b5438392602e3f4c36f09295b134ca4f Mon Sep 17 00:00:00 2001 From: Jan Wassenberg Date: Fri, 17 Jan 2025 02:29:04 -0800 Subject: [PATCH] add HWY_UNREACHABLE and add documentation for related macros PiperOrigin-RevId: 716584567 --- g3doc/quick_reference.md | 13 +++++++++++++ hwy/base.h | 6 ++++++ hwy/base_test.cc | 9 +++++++++ 3 files changed, 28 insertions(+) diff --git a/g3doc/quick_reference.md b/g3doc/quick_reference.md index 7bf7c0b932..e3a338d69a 100644 --- a/g3doc/quick_reference.md +++ b/g3doc/quick_reference.md @@ -2476,6 +2476,19 @@ Ops in this section are only available if `HWY_TARGET != HWY_SCALAR`: * `HWY_ALIGN_MAX`: as `HWY_ALIGN`, but independent of `HWY_TARGET` and may be used outside `HWY_NAMESPACE`. +* `HWY_RESTRICT`: use after a pointer, e.g. `T* HWY_RESTRICT p`, to indicate + the pointer is not aliased, i.e. it is the only way to access the data. This + may improve code generation by preventing unnecessary reloads. + +* `HWY_LIKELY`: use `if (HWY_LIKELY(condition))` to signal to the compiler + that `condition` is likely to be true. This may improve performance by + influencing the layout of the generated code. + +* `HWY_UNLIKELY`: like `HWY_LIKELY`, but for conditions likely to be false. + +* `HWY_UNREACHABLE;`: signals to the compiler that control will never reach + this point, which may improve code generation. + ## Advanced macros Beware that these macros describe the current target being compiled. Imagine a diff --git a/hwy/base.h b/hwy/base.h index f2dc87c0c5..0219503f4c 100644 --- a/hwy/base.h +++ b/hwy/base.h @@ -101,6 +101,7 @@ #define HWY_NORETURN __declspec(noreturn) #define HWY_LIKELY(expr) (expr) #define HWY_UNLIKELY(expr) (expr) +#define HWY_UNREACHABLE __assume(false) #define HWY_PRAGMA(tokens) __pragma(tokens) #define HWY_DIAGNOSTICS(tokens) HWY_PRAGMA(warning(tokens)) #define HWY_DIAGNOSTICS_OFF(msc, gcc) HWY_DIAGNOSTICS(msc) @@ -128,6 +129,11 @@ #define HWY_NORETURN __attribute__((noreturn)) #define HWY_LIKELY(expr) __builtin_expect(!!(expr), 1) #define HWY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) +#if HWY_COMPILER_GCC || __has_builtin(__builtin_unreachable) +#define HWY_UNREACHABLE __builtin_unreachable() +#else +#define HWY_UNREACHABLE +#endif #define HWY_PRAGMA(tokens) _Pragma(#tokens) #define HWY_DIAGNOSTICS(tokens) HWY_PRAGMA(GCC diagnostic tokens) #define HWY_DIAGNOSTICS_OFF(msc, gcc) HWY_DIAGNOSTICS(gcc) diff --git a/hwy/base_test.cc b/hwy/base_test.cc index a22da3aa64..b1eb953b79 100644 --- a/hwy/base_test.cc +++ b/hwy/base_test.cc @@ -17,6 +17,8 @@ #include +#include "hwy/nanobenchmark.h" + #undef HWY_TARGET_INCLUDE #define HWY_TARGET_INCLUDE "base_test.cc" #include "hwy/foreach_target.h" // IWYU pragma: keep @@ -28,6 +30,12 @@ namespace hwy { namespace HWY_NAMESPACE { namespace { +HWY_NOINLINE void TestUnreachable() { + if (!hwy::Unpredictable1()) { + HWY_UNREACHABLE; + } +} + HWY_NOINLINE void TestAllLimits() { HWY_ASSERT_EQ(uint8_t{0}, LimitsMin()); HWY_ASSERT_EQ(uint16_t{0}, LimitsMin()); @@ -848,6 +856,7 @@ HWY_AFTER_NAMESPACE(); namespace hwy { namespace { HWY_BEFORE_TEST(BaseTest); +HWY_EXPORT_AND_TEST_P(BaseTest, TestUnreachable); HWY_EXPORT_AND_TEST_P(BaseTest, TestAllLimits); HWY_EXPORT_AND_TEST_P(BaseTest, TestAllLowestHighest); HWY_EXPORT_AND_TEST_P(BaseTest, TestAllType);