Recently, I discovered void __builtin_assume(bool)
for clang, which can provide additional information about the state of the program to the compiler. This can make a huge difference, like for example:
#include <cstddef>
// compiles to about 80 instructions at -O3
unsigned sum(unsigned data[], size_t count) {
unsigned sum = 0;
for (size_t i = 0; i < count; ++i) {
sum += data[i];
}
return sum;
}
// compiles to about 10 instructions at -O3
unsigned sum_small(unsigned data[], size_t count) {
__builtin_assume(count <= 4);
unsigned sum = 0;
for (size_t i = 0; i < count; ++i) {
sum += data[i];
}
return sum;
}
I am forced to use GCC at this time and I am curious whether there exists an equivalent builtin. Unfortunately I could not find __builtin_assume
in the GCC documentation. Maybe there exists a builtin but it just has a different name?
If there doesn't exist an equivalent builtin, is there maybe a way to produce the same result without __builtin_assume
, such as intentionally invoking undefined behavior when the condition is not true?
Ideally, I would like a macro which is always safe to call like:
#if ... // detect clang
#define MY_ASSUME(condition) __builtin_assume(condition)
#elif ... // detect GCC
#define MY_ASSUME(condition) __gcc_builtin_assume_equivalent(condition)
#else
#define MY_ASSUME(condition)
#endif
Whatever the solution is, it should also work in a constexpr
function.
Since C++23, this is possible using the
[[assume]]
attribute. This works just like clang's__builtin_assume
. There is also an__attribute__((__assume__(...))
that works in C and C++.Definition of Assumption Macro
Usage Example
It may take some time for all compilers to implement
[[assume]]
, but as you can see, there are plenty fallback options. As of the time of writing, only GCC 13 supports this.See also: C++23 Compiler Support