[libc] Fix exp2f and prevent misuse of likely/unlikely
authorGuillaume Chatelet <gchatelet@google.com>
Fri, 10 Feb 2023 13:49:03 +0000 (13:49 +0000)
committerGuillaume Chatelet <gchatelet@google.com>
Fri, 10 Feb 2023 14:01:48 +0000 (14:01 +0000)
Let's make sure that we only accept boolean expressions when using likely/unlikely.

Differential Revision: https://reviews.llvm.org/D143732

libc/src/__support/macros/attributes.h
libc/src/math/generic/exp2f.cpp

index 7be34bd..e949627 100644 (file)
 
 #define LIBC_INLINE inline
 #define LIBC_INLINE_ASM __asm__ __volatile__
-#define LIBC_LIKELY(x) __builtin_expect(!!(x), 1)
-#define LIBC_UNLIKELY(x) __builtin_expect(x, 0)
+
+// We use a template to implement likely/unlikely to make sure that we don't
+// accidentally pass an integer.
+namespace __llvm_libc::details {
+template <typename T>
+constexpr LIBC_INLINE bool expects_bool_condition(T value, T expected) {
+  return __builtin_expect(value, expected);
+}
+} // namespace __llvm_libc::details
+#define LIBC_LIKELY(x) __llvm_libc::details::expects_bool_condition(x, true)
+#define LIBC_UNLIKELY(x) __llvm_libc::details::expects_bool_condition(x, false)
+
 #define LIBC_UNUSED __attribute__((unused))
 
 #endif // LLVM_LIBC_SUPPORT_MACROS_ATTRIBUTES_H
index 835f3ed..52ae89a 100644 (file)
@@ -69,7 +69,7 @@ LLVM_LIBC_FUNCTION(float, exp2f, (float x)) {
   }
 
   // Check exceptional values.
-  if (LIBC_UNLIKELY(x_u & exval_mask) == exval_mask) {
+  if (LIBC_UNLIKELY((x_u & exval_mask) == exval_mask)) {
     if (LIBC_UNLIKELY(x_u == exval1)) { // x = 0x1.853a6ep-9f
       if (fputil::get_round() == FE_TONEAREST)
         return 0x1.00870ap+0f;