diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 14 | ||||
| -rw-r--r-- | clang/test/CodeGen/c11atomics-ios.c | 16 | ||||
| -rw-r--r-- | clang/test/CodeGen/c11atomics.c | 14 |
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); +} |

