Index: include/clang/Basic/DiagnosticGroups.td =================================================================== --- include/clang/Basic/DiagnosticGroups.td +++ include/clang/Basic/DiagnosticGroups.td @@ -859,6 +859,8 @@ def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">; def ProfileInstrUnprofiled : DiagGroup<"profile-instr-unprofiled">; +def AtomicLibcall : DiagGroup<"atomic-libcall">; + // AddressSanitizer frontent instrumentation remarks. def SanitizeAddressRemarks : DiagGroup<"sanitize-address">; @@ -880,4 +882,4 @@ // A warning group for warnings about code that clang accepts when // compiling OpenCL C/C++ but which is not compatible with the SPIR spec. -def SpirCompat : DiagGroup<"spir-compat">; \ No newline at end of file +def SpirCompat : DiagGroup<"spir-compat">; Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -5118,6 +5118,8 @@ "_Atomic cannot be applied to " "%select{incomplete |array |function |reference |atomic |qualified |}0type " "%1 %select{||||||which is not trivially copyable}0">; +def warn_atomic_builtin_expands_to_libcall : Warning< + "atomic builtin expands to library call">, InGroup, DefaultIgnore; // Expressions. def ext_sizeof_alignof_function_type : Extension< Index: lib/Sema/SemaChecking.cpp =================================================================== --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -3035,6 +3035,15 @@ ASTContext& Context = this->getASTContext(); + // Warn if the requested atomic will expand into a library call, as this can + // impact performance significantly if it requires kernel intervention or + // some other shared but hidden lock. + if (Context.getTypeSizeInChars(ValType) > + Context.toCharUnitsFromBits( + Context.getTargetInfo().getMaxAtomicInlineWidth())) { + Diag(DRE->getLocStart(), diag::warn_atomic_builtin_expands_to_libcall); + } + // Create a new DeclRefExpr to refer to the new decl. DeclRefExpr* NewDRE = DeclRefExpr::Create( Context, Index: test/Sema/atomic-libcall.c =================================================================== --- /dev/null +++ test/Sema/atomic-libcall.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only -triple=mips-mti-linux-gnu -Watomic-libcall + +// Test that larger than word size atomics are warned about. + +long long var; + +void foo(long long a) { + __sync_fetch_and_add(&var, 0, a); // expected-warning {{atomic builtin expands to library call}} +}