diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -1480,6 +1480,7 @@ BUILTIN(__builtin_char_memchr, "c*cC*iz", "n") BUILTIN(__builtin_dump_struct, "ivC*v*", "tn") BUILTIN(__builtin_preserve_access_index, "v.", "t") +BUILTIN(__builtin_get_cpu_cache_line_size, "zv", "nc") // Alignment builtins (uses custom parsing to support pointers and integers) BUILTIN(__builtin_is_aligned, "bvC*z", "nct") diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -10915,6 +10915,14 @@ return Success(Info.InConstantContext, E); } + case Builtin::BI__builtin_get_cpu_cache_line_size: { + Optional cacheLineSize = + Info.Ctx.getTargetInfo().getCPUCacheLineSize(); + if (cacheLineSize.hasValue()) + return Success(cacheLineSize.getValue(), E); + return Success(0, E); + } + case Builtin::BI__builtin_ctz: case Builtin::BI__builtin_ctzl: case Builtin::BI__builtin_ctzll: diff --git a/clang/test/SemaCXX/builtin-cache-line-size.cpp b/clang/test/SemaCXX/builtin-cache-line-size.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/builtin-cache-line-size.cpp @@ -0,0 +1,32 @@ +// RUN: %clang -mcpu=i368 %s +// RUN: ./a.out + +#include + +size_t a() { + return __builtin_get_cpu_cache_line_size(); +} + +size_t b(bool x) { + if (x) { + return __builtin_get_cpu_cache_line_size(); + } + return 0; +} + +int main() { + assert(a() == 64); + assert(b(true) == 64); + assert(b(false) == 0); +} + +// This is based on the value for i368. +static_assert(__builtin_get_cpu_cache_line_size() == 64, ""); + +struct keep_apart { + alignas(__builtin_get_cpu_cache_line_size()) int cat; + alignas(__builtin_get_cpu_cache_line_size()) int dog; +}; + +static_assert(sizeof(keep_apart) == __builtin_get_cpu_cache_line_size() * 2 || + __builtin_get_cpu_cache_line_size() == 0, "");