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 @@ -525,6 +525,8 @@ BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:") BUILTIN(__builtin_thread_pointer, "v*", "nc") BUILTIN(__builtin_launder, "v*v*", "nt") +LANGBUILTIN(__builtin_hardware_destructive_interference_size, "i", "n", CXX_LANG) +LANGBUILTIN(__builtin_hardware_constructive_interference_size, "i", "n", CXX_LANG) LANGBUILTIN(__builtin_is_constant_evaluated, "b", "n", CXX_LANG) // GCC exception builtins 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 @@ -9478,6 +9478,40 @@ return ExprEvaluatorBaseTy::VisitCallExpr(E); } +static unsigned getCacheLineSize(llvm::Triple::ArchType Arch) { + switch (Arch) { + case llvm::Triple::arm: + case llvm::Triple::armeb: + case llvm::Triple::thumb: + case llvm::Triple::thumbeb: + // This value is between 8 and 64. We are using the upper bound to be safe. + return 64; + case llvm::Triple::aarch64: + case llvm::Triple::aarch64_be: + // Sometimes bit.LITTLE will have cores with both a 64 and 128 line sizes. + return 128; + case llvm::Triple::x86: + case llvm::Triple::x86_64: + return 64; + case llvm::Triple::ppc: + case llvm::Triple::ppc64: + case llvm::Triple::ppc64le: + return 128; + case llvm::Triple::r600: + case llvm::Triple::amdgcn: + return 64; + case llvm::Triple::nvptx: + case llvm::Triple::nvptx64: + return 64; + case llvm::Triple::systemz: + case llvm::Triple::wasm32: + case llvm::Triple::wasm64: + case llvm::Triple::hexagon: + default: + return 0; + } +} + bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, unsigned BuiltinOp) { switch (unsigned BuiltinOp = E->getBuiltinCallee()) { @@ -9575,6 +9609,12 @@ case Builtin::BI__builtin_is_constant_evaluated: return Success(Info.InConstantContext, E); + case Builtin::BI__builtin_hardware_destructive_interference_size: + case Builtin::BI__builtin_hardware_constructive_interference_size: { + unsigned cacheLineSize + = getCacheLineSize(Info.Ctx.getTargetInfo().getTriple().getArch()); + return Success(cacheLineSize, E); + } case Builtin::BI__builtin_ctz: case Builtin::BI__builtin_ctzl: diff --git a/clang/test/Sema/builtins.c b/clang/test/Sema/builtins.c --- a/clang/test/Sema/builtins.c +++ b/clang/test/Sema/builtins.c @@ -234,7 +234,7 @@ strlcat(buf, b, sizeof(b)); // expected-warning {{size argument in 'strlcat' call appears to be size of the source; expected the size of the destination}} \ // expected-note {{change size argument to be the size of the destination}} - + __builtin___strlcat_chk(buf, b, sizeof(b), __builtin_object_size(buf, 0)); // expected-warning {{size argument in '__builtin___strlcat_chk' call appears to be size of the source; expected the size of the destination}} \ // expected-note {{change size argument to be the size of the destination}} \ // expected-warning {{'strlcat' will always overflow; destination buffer has size 20, but size argument is 40}} @@ -315,8 +315,16 @@ my_memcpy(buf, src, 11); // expected-warning{{'memcpy' will always overflow; destination buffer has size 10, but size argument is 11}} } -// Test that __builtin_is_constant_evaluated() is not allowed in C -int test_cxx_builtin() { +// Test that C++ builtins are not allowed in C +void test_cxx_builtin() { // expected-error@+1 {{use of unknown builtin '__builtin_is_constant_evaluated'}} - return __builtin_is_constant_evaluated(); + (void)__builtin_is_constant_evaluated(); + + // expected-error@+2 {{use of unknown builtin '__builtin_hardware_destructive_interference_size'}} + // expected-note@+1 {{'__builtin_hardware_destructive_interference_size' declared here}} + (void)__builtin_hardware_destructive_interference_size(); + + // expected-error@+2 {{use of unknown builtin '__builtin_hardware_constructive_interference_size'}} + // expected-note@+1 {{did you mean '__builtin_hardware_destructive_interference_size'?}} + (void)__builtin_hardware_constructive_interference_size(); } diff --git a/clang/test/SemaCXX/builtin-hardware-interference-size-aarch.cpp b/clang/test/SemaCXX/builtin-hardware-interference-size-aarch.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/builtin-hardware-interference-size-aarch.cpp @@ -0,0 +1,7 @@ +// expected-no-diagnostics +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=aarch64-linux-gnu +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=aarch64_be-linux-gnu +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=aarch64-apple-darwin16.0.0 + +static_assert(__builtin_hardware_constructive_interference_size() == 128); +static_assert(__builtin_hardware_destructive_interference_size() == 128); diff --git a/clang/test/SemaCXX/builtin-hardware-interference-size-amd.cpp b/clang/test/SemaCXX/builtin-hardware-interference-size-amd.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/builtin-hardware-interference-size-amd.cpp @@ -0,0 +1,7 @@ +// expected-no-diagnostics +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=r600-linux-gnu +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=amdgcn-linux-gnu +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=amdgcn-apple-darwin16.0.0 + +static_assert(__builtin_hardware_constructive_interference_size() == 64); +static_assert(__builtin_hardware_destructive_interference_size() == 64); diff --git a/clang/test/SemaCXX/builtin-hardware-interference-size-arm.cpp b/clang/test/SemaCXX/builtin-hardware-interference-size-arm.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/builtin-hardware-interference-size-arm.cpp @@ -0,0 +1,9 @@ +// expected-no-diagnostics +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=arm-linux-gnu +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=armeb-linux-gnu +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=thumb-linux-gnu +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=thumbeb-linux-gnu +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=arm-apple-darwin16.0.0 + +static_assert(__builtin_hardware_constructive_interference_size() == 64); +static_assert(__builtin_hardware_destructive_interference_size() == 64); diff --git a/clang/test/SemaCXX/builtin-hardware-interference-size-nvptx.cpp b/clang/test/SemaCXX/builtin-hardware-interference-size-nvptx.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/builtin-hardware-interference-size-nvptx.cpp @@ -0,0 +1,7 @@ +// expected-no-diagnostics +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=nvptx-linux-gnu +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=nvptx64-linux-gnu +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=nvptx-apple-darwin16.0.0 + +static_assert(__builtin_hardware_constructive_interference_size() == 64); +static_assert(__builtin_hardware_destructive_interference_size() == 64); diff --git a/clang/test/SemaCXX/builtin-hardware-interference-size-ppc.cpp b/clang/test/SemaCXX/builtin-hardware-interference-size-ppc.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/builtin-hardware-interference-size-ppc.cpp @@ -0,0 +1,8 @@ +// expected-no-diagnostics +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=ppc-linux-gnu +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=ppc64-linux-gnu +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=ppc64le-linux-gnu +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=ppc-apple-darwin16.0.0 + +static_assert(__builtin_hardware_constructive_interference_size() == 128); +static_assert(__builtin_hardware_destructive_interference_size() == 128); diff --git a/clang/test/SemaCXX/builtin-hardware-interference-size-unknown.cpp b/clang/test/SemaCXX/builtin-hardware-interference-size-unknown.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/builtin-hardware-interference-size-unknown.cpp @@ -0,0 +1,9 @@ +// expected-no-diagnostics +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=systemz-linux-gnu +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=wasm32-unknown-unknown +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=wasm64-unknown-unknown +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=hexagon-linux-gnu +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=systemz-apple-darwin16.0.0 + +static_assert(__builtin_hardware_constructive_interference_size() == 0); +static_assert(__builtin_hardware_destructive_interference_size() == 0); diff --git a/clang/test/SemaCXX/builtin-hardware-interference-size-x86.cpp b/clang/test/SemaCXX/builtin-hardware-interference-size-x86.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/builtin-hardware-interference-size-x86.cpp @@ -0,0 +1,7 @@ +// expected-no-diagnostics +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=x86_64-unknown-unknown +// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=x86_64-apple-darwin16.0.0 + +static_assert(__builtin_hardware_constructive_interference_size() == 64); +static_assert(__builtin_hardware_destructive_interference_size() == 64);