Skip to content

Commit

Permalink
Reinstall the patch "Use EmitPointerWithAlignment to get alignment in…
Browse files Browse the repository at this point in the history
…formation of the pointer used in atomic expr".

This is to fix PR34347. EmitAtomicExpr now only uses alignment information from
Type, instead of Decl, so when the declaration of an atomic variable is marked
to have the alignment equal as its size, EmitAtomicExpr doesn't know about it and
will generate libcall instead of atomic op. The patch uses EmitPointerWithAlignment
to get the precise alignment information.

Differential Revision: https://reviews.llvm.org/D37310


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@312830 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
wmi-11 committed Sep 8, 2017
1 parent 51a7f4d commit 6c5d281
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 8 deletions.
16 changes: 8 additions & 8 deletions lib/CodeGen/CGAtomic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -745,19 +745,19 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
QualType MemTy = AtomicTy;
if (const AtomicType *AT = AtomicTy->getAs<AtomicType>())
MemTy = AT->getValueType();
CharUnits sizeChars, alignChars;
std::tie(sizeChars, alignChars) = getContext().getTypeInfoInChars(AtomicTy);
uint64_t Size = sizeChars.getQuantity();
unsigned MaxInlineWidthInBits = getTarget().getMaxAtomicInlineWidth();
bool UseLibcall = (sizeChars != alignChars ||
getContext().toBits(sizeChars) > MaxInlineWidthInBits);

llvm::Value *IsWeak = nullptr, *OrderFail = nullptr;

Address Val1 = Address::invalid();
Address Val2 = Address::invalid();
Address Dest = Address::invalid();
Address Ptr(EmitScalarExpr(E->getPtr()), alignChars);
Address Ptr = EmitPointerWithAlignment(E->getPtr());

CharUnits sizeChars, alignChars;
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 (E->getOp() == AtomicExpr::AO__c11_atomic_init ||
E->getOp() == AtomicExpr::AO__opencl_atomic_init) {
Expand Down
30 changes: 30 additions & 0 deletions test/CodeGenCXX/atomic-align.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=x86_64-linux-gnu | FileCheck %s

struct AM {
int f1, f2;
};
alignas(8) AM m;
AM load1() {
AM am;
// m is declared to align to 8bytes, so generate load atomic instead
// of libcall.
// CHECK-LABEL: @_Z5load1v
// CHECK: load atomic {{.*}} monotonic
__atomic_load(&m, &am, 0);
return am;
}

struct BM {
int f1;
alignas(8) AM f2;
};
BM bm;
AM load2() {
AM am;
// BM::f2 is declared to align to 8bytes, so generate load atomic instead
// of libcall.
// CHECK-LABEL: @_Z5load2v
// CHECK: load atomic {{.*}} monotonic
__atomic_load(&bm.f2, &am, 0);
return am;
}

0 comments on commit 6c5d281

Please sign in to comment.