Author: tnorthover Date: Mon Apr 23 01:16:24 2018 New Revision: 330566 URL: http://llvm.org/viewvc/llvm-project?rev=330566&view=rev Log: [Atomics] warn about atomic accesses using libcalls
If an atomic variable is misaligned (and that suspicion is why Clang emits libcalls at all) the runtime support library will have to use a lock to safely access it, with potentially very bad performance consequences. There's a very good chance this is unintentional so it makes sense to issue a warning. Also give it a named group so people can promote it to an error, or disable it if they really don't care. Added: cfe/trunk/test/CodeGen/atomics-sema-alignment.c Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/CodeGen/CGAtomic.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=330566&r1=330565&r2=330566&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Apr 23 01:16:24 2018 @@ -7111,6 +7111,9 @@ def warn_atomic_op_has_invalid_memory_or InGroup<DiagGroup<"atomic-memory-ordering">>; def err_atomic_op_has_invalid_synch_scope : Error< "synchronization scope argument to atomic operation is invalid">; +def warn_atomic_op_misaligned : Warning< + "misaligned or large atomic operation may incur significant performance penalty">, + InGroup<DiagGroup<"atomic-alignment">>; def err_overflow_builtin_must_be_int : Error< "operand argument to overflow builtin must be an integer (%0 invalid)">; Modified: cfe/trunk/lib/CodeGen/CGAtomic.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGAtomic.cpp?rev=330566&r1=330565&r2=330566&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGAtomic.cpp (original) +++ cfe/trunk/lib/CodeGen/CGAtomic.cpp Mon Apr 23 01:16:24 2018 @@ -18,6 +18,7 @@ #include "TargetInfo.h" #include "clang/AST/ASTContext.h" #include "clang/CodeGen/CGFunctionInfo.h" +#include "clang/Sema/SemaDiagnostic.h" #include "llvm/ADT/DenseMap.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Intrinsics.h" @@ -751,6 +752,13 @@ RValue CodeGenFunction::EmitAtomicExpr(A Address Dest = Address::invalid(); Address Ptr = EmitPointerWithAlignment(E->getPtr()); + if (E->getOp() == AtomicExpr::AO__c11_atomic_init || + E->getOp() == AtomicExpr::AO__opencl_atomic_init) { + LValue lvalue = MakeAddrLValue(Ptr, AtomicTy); + EmitAtomicInit(E->getVal1(), lvalue); + return RValue::get(nullptr); + } + CharUnits sizeChars, alignChars; std::tie(sizeChars, alignChars) = getContext().getTypeInfoInChars(AtomicTy); uint64_t Size = sizeChars.getQuantity(); @@ -758,12 +766,8 @@ RValue CodeGenFunction::EmitAtomicExpr(A bool UseLibcall = ((Ptr.getAlignment() % sizeChars) != 0 || getContext().toBits(sizeChars) > MaxInlineWidthInBits); - if (E->getOp() == AtomicExpr::AO__c11_atomic_init || - E->getOp() == AtomicExpr::AO__opencl_atomic_init) { - LValue lvalue = MakeAddrLValue(Ptr, AtomicTy); - EmitAtomicInit(E->getVal1(), lvalue); - return RValue::get(nullptr); - } + if (UseLibcall) + CGM.getDiags().Report(E->getLocStart(), diag::warn_atomic_op_misaligned); llvm::Value *Order = EmitScalarExpr(E->getOrder()); llvm::Value *Scope = Added: cfe/trunk/test/CodeGen/atomics-sema-alignment.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/atomics-sema-alignment.c?rev=330566&view=auto ============================================================================== --- cfe/trunk/test/CodeGen/atomics-sema-alignment.c (added) +++ cfe/trunk/test/CodeGen/atomics-sema-alignment.c Mon Apr 23 01:16:24 2018 @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu %s -emit-llvm -o /dev/null -verify + +typedef struct { + int a, b; +} IntPair; + +typedef struct { + long long a; +} LongStruct; + +typedef int __attribute__((aligned(1))) unaligned_int; + +void func(IntPair *p) { + IntPair res; + __atomic_load(p, &res, 0); // expected-warning {{misaligned or large atomic operation may incur significant performance penalty}} + __atomic_store(p, &res, 0); // expected-warning {{misaligned or large atomic operation may incur significant performance penalty}} + __atomic_fetch_add((unaligned_int *)p, 1, 2); // expected-warning {{misaligned or large atomic operation may incur significant performance penalty}} + __atomic_fetch_sub((unaligned_int *)p, 1, 3); // expected-warning {{misaligned or large atomic operation may incur significant performance penalty}} +} + +void func1(LongStruct *p) { + LongStruct res; + __atomic_load(p, &res, 0); + __atomic_store(p, &res, 0); + __atomic_fetch_add((int *)p, 1, 2); + __atomic_fetch_sub((int *)p, 1, 3); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits