summaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGAtomic.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
commit676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63 (patch)
tree02a1ac369cb734d0abfa5000dd86e5b7797e6a74 /lib/CodeGen/CGAtomic.cpp
parentc7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (diff)
Diffstat (limited to 'lib/CodeGen/CGAtomic.cpp')
-rw-r--r--lib/CodeGen/CGAtomic.cpp28
1 files changed, 19 insertions, 9 deletions
diff --git a/lib/CodeGen/CGAtomic.cpp b/lib/CodeGen/CGAtomic.cpp
index b34bcdc1fc38d..24056a449def4 100644
--- a/lib/CodeGen/CGAtomic.cpp
+++ b/lib/CodeGen/CGAtomic.cpp
@@ -18,7 +18,7 @@
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/CodeGen/CGFunctionInfo.h"
-#include "clang/Sema/SemaDiagnostic.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Intrinsics.h"
@@ -765,11 +765,15 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
std::tie(sizeChars, alignChars) = getContext().getTypeInfoInChars(AtomicTy);
uint64_t Size = sizeChars.getQuantity();
unsigned MaxInlineWidthInBits = getTarget().getMaxAtomicInlineWidth();
- bool UseLibcall = ((Ptr.getAlignment() % sizeChars) != 0 ||
- getContext().toBits(sizeChars) > MaxInlineWidthInBits);
- if (UseLibcall)
- CGM.getDiags().Report(E->getLocStart(), diag::warn_atomic_op_misaligned);
+ bool Oversized = getContext().toBits(sizeChars) > MaxInlineWidthInBits;
+ bool Misaligned = (Ptr.getAlignment() % sizeChars) != 0;
+ bool UseLibcall = Misaligned | Oversized;
+
+ if (UseLibcall) {
+ CGM.getDiags().Report(E->getBeginLoc(), diag::warn_atomic_op_misaligned)
+ << !Oversized;
+ }
llvm::Value *Order = EmitScalarExpr(E->getOrder());
llvm::Value *Scope =
@@ -923,6 +927,15 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
UseOptimizedLibcall = true;
break;
+ case AtomicExpr::AO__atomic_load:
+ case AtomicExpr::AO__atomic_store:
+ case AtomicExpr::AO__atomic_exchange:
+ case AtomicExpr::AO__atomic_compare_exchange:
+ // Use the generic version if we don't know that the operand will be
+ // suitably aligned for the optimized version.
+ if (Misaligned)
+ break;
+ LLVM_FALLTHROUGH;
case AtomicExpr::AO__c11_atomic_load:
case AtomicExpr::AO__c11_atomic_store:
case AtomicExpr::AO__c11_atomic_exchange:
@@ -934,14 +947,11 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
case AtomicExpr::AO__atomic_load_n:
- case AtomicExpr::AO__atomic_load:
case AtomicExpr::AO__atomic_store_n:
- case AtomicExpr::AO__atomic_store:
case AtomicExpr::AO__atomic_exchange_n:
- case AtomicExpr::AO__atomic_exchange:
case AtomicExpr::AO__atomic_compare_exchange_n:
- case AtomicExpr::AO__atomic_compare_exchange:
// Only use optimized library calls for sizes for which they exist.
+ // FIXME: Size == 16 optimized library functions exist too.
if (Size == 1 || Size == 2 || Size == 4 || Size == 8)
UseOptimizedLibcall = true;
break;