summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/AST/ASTContext.cpp14
-rw-r--r--clang/test/CodeGen/c11atomics-ios.c16
-rw-r--r--clang/test/CodeGen/c11atomics.c14
3 files changed, 40 insertions, 4 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index f8de2b44809..0f76136e351 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1958,10 +1958,16 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Width = Info.Width;
Align = Info.Align;
- // If the size of the type doesn't exceed the platform's max
- // atomic promotion width, make the size and alignment more
- // favorable to atomic operations:
- if (Width != 0 && Width <= Target->getMaxAtomicPromoteWidth()) {
+ if (!Width) {
+ // An otherwise zero-sized type should still generate an
+ // atomic operation.
+ Width = Target->getCharWidth();
+ assert(Align);
+ } else if (Width <= Target->getMaxAtomicPromoteWidth()) {
+ // If the size of the type doesn't exceed the platform's max
+ // atomic promotion width, make the size and alignment more
+ // favorable to atomic operations:
+
// Round the size up to a power of 2.
if (!llvm::isPowerOf2_64(Width))
Width = llvm::NextPowerOf2(Width);
diff --git a/clang/test/CodeGen/c11atomics-ios.c b/clang/test/CodeGen/c11atomics-ios.c
index 0e24ed228ca..f48e10e4aa4 100644
--- a/clang/test/CodeGen/c11atomics-ios.c
+++ b/clang/test/CodeGen/c11atomics-ios.c
@@ -319,3 +319,19 @@ _Bool test_promoted_cmpxchg(_Atomic(PS) *addr, PS *desired, PS *new) {
return __c11_atomic_compare_exchange_strong(addr, desired, *new, 5, 5);
}
+
+struct Empty {};
+
+struct Empty testEmptyStructLoad(_Atomic(struct Empty)* empty) {
+ // CHECK-LABEL: @testEmptyStructLoad(
+ // CHECK-NOT: @__atomic_load
+ // CHECK: load atomic i8, i8* %{{.*}} seq_cst, align 1
+ return *empty;
+}
+
+void testEmptyStructStore(_Atomic(struct Empty)* empty, struct Empty value) {
+ // CHECK-LABEL: @testEmptyStructStore(
+ // CHECK-NOT: @__atomic_store
+ // CHECK: store atomic i8 %{{.*}}, i8* %{{.*}} seq_cst, align 1
+ *empty = value;
+}
diff --git a/clang/test/CodeGen/c11atomics.c b/clang/test/CodeGen/c11atomics.c
index 3774ded7c42..cf251738be5 100644
--- a/clang/test/CodeGen/c11atomics.c
+++ b/clang/test/CodeGen/c11atomics.c
@@ -474,3 +474,17 @@ _Bool test_promoted_cmpxchg(_Atomic(PS) *addr, PS *desired, PS *new) {
// CHECK: ret i1 [[RES]]
return __c11_atomic_compare_exchange_strong(addr, desired, *new, 5, 5);
}
+
+struct Empty {};
+
+struct Empty test_empty_struct_load(_Atomic(struct Empty)* empty) {
+ // CHECK-LABEL: @test_empty_struct_load(
+ // CHECK: call arm_aapcscc zeroext i8 @__atomic_load_1(i8* %{{.*}}, i32 5)
+ return __c11_atomic_load(empty, 5);
+}
+
+void test_empty_struct_store(_Atomic(struct Empty)* empty, struct Empty value) {
+ // CHECK-LABEL: @test_empty_struct_store(
+ // CHECK: call arm_aapcscc void @__atomic_store_1(i8* %{{.*}}, i8 zeroext %{{.*}}, i32 5)
+ __c11_atomic_store(empty, value, 5);
+}
OpenPOWER on IntegriCloud