Skip to content

Commit 909250d

Browse files
davidbentmsri
authored andcommitted
[libc++] Make _LIBCPP_ASSUME usable when it is appropriate (llvm#91801)
libc++ turned off _LIBCPP_ASSUME because turning every debug assert into __builtin_assume tripped [1]. However, this means we can't use _LIBCPP_ASSUME when there is a clear optimization intent. See [2] for discussion of a place where _LIBCPP_ASSUME would be valuable. This patch fixes this by not undefining the definition of _LIBCPP_ASSUME and making sure that we don't attempt to `_LIBCPP_ASSSUME` every assertion in the library. [1]: https://discourse.llvm.org/t/llvm-assume-blocks-optimization/71609 [2]: llvm#78929 (comment)
1 parent 2777c56 commit 909250d

File tree

1 file changed

+28
-28
lines changed

1 file changed

+28
-28
lines changed

libcxx/include/__assert

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@
2323
: _LIBCPP_ASSERTION_HANDLER(__FILE__ ":" _LIBCPP_TOSTRING(__LINE__) ": assertion " _LIBCPP_TOSTRING( \
2424
expression) " failed: " message "\n"))
2525

26-
// TODO: __builtin_assume can currently inhibit optimizations. Until this has been fixed and we can add
27-
// assumptions without a clear optimization intent, disable that to avoid worsening the code generation.
28-
// See https://discourse.llvm.org/t/llvm-assume-blocks-optimization/71609 for a discussion.
29-
#if 0 && __has_builtin(__builtin_assume)
26+
// WARNING: __builtin_assume can currently inhibit optimizations. Only add assumptions with a clear
27+
// optimization intent. See https://discourse.llvm.org/t/llvm-assume-blocks-optimization/71609 for a
28+
// discussion.
29+
#if __has_builtin(__builtin_assume)
3030
# define _LIBCPP_ASSUME(expression) \
3131
(_LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wassume") \
3232
__builtin_assume(static_cast<bool>(expression)) _LIBCPP_DIAGNOSTIC_POP)
@@ -44,18 +44,18 @@
4444
# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message)
4545
// Disabled checks.
4646
// On most modern platforms, dereferencing a null pointer does not lead to an actual memory access.
47-
# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSUME(expression)
47+
# define _LIBCPP_ASSERT_NON_NULL(expression, message) ((void)0)
4848
// Overlapping ranges will make algorithms produce incorrect results but don't directly lead to a security
4949
// vulnerability.
50-
# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSUME(expression)
51-
# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) _LIBCPP_ASSUME(expression)
52-
# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) _LIBCPP_ASSUME(expression)
53-
# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression)
54-
# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) _LIBCPP_ASSUME(expression)
55-
# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSUME(expression)
56-
# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSUME(expression)
57-
# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression)
58-
# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression)
50+
# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) ((void)0)
51+
# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) ((void)0)
52+
# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) ((void)0)
53+
# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) ((void)0)
54+
# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) ((void)0)
55+
# define _LIBCPP_ASSERT_PEDANTIC(expression, message) ((void)0)
56+
# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) ((void)0)
57+
# define _LIBCPP_ASSERT_INTERNAL(expression, message) ((void)0)
58+
# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) ((void)0)
5959

6060
// Extensive hardening mode checks.
6161

@@ -73,8 +73,8 @@
7373
# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSERT(expression, message)
7474
# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message)
7575
// Disabled checks.
76-
# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSUME(expression)
77-
# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression)
76+
# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) ((void)0)
77+
# define _LIBCPP_ASSERT_INTERNAL(expression, message) ((void)0)
7878

7979
// Debug hardening mode checks.
8080

@@ -99,18 +99,18 @@
9999
#else
100100

101101
// All checks disabled.
102-
# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSUME(expression)
103-
# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSUME(expression)
104-
# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSUME(expression)
105-
# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSUME(expression)
106-
# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) _LIBCPP_ASSUME(expression)
107-
# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) _LIBCPP_ASSUME(expression)
108-
# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression)
109-
# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) _LIBCPP_ASSUME(expression)
110-
# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSUME(expression)
111-
# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSUME(expression)
112-
# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression)
113-
# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression)
102+
# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) ((void)0)
103+
# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) ((void)0)
104+
# define _LIBCPP_ASSERT_NON_NULL(expression, message) ((void)0)
105+
# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) ((void)0)
106+
# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) ((void)0)
107+
# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) ((void)0)
108+
# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) ((void)0)
109+
# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) ((void)0)
110+
# define _LIBCPP_ASSERT_PEDANTIC(expression, message) ((void)0)
111+
# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) ((void)0)
112+
# define _LIBCPP_ASSERT_INTERNAL(expression, message) ((void)0)
113+
# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) ((void)0)
114114

115115
#endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST
116116
// clang-format on

0 commit comments

Comments
 (0)