From: Anastasia Stulova Date: Tue, 22 Dec 2015 15:14:54 +0000 (+0000) Subject: [OpenCL] Fix atomic Builtins check for address spaces of non-atomic pointer X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2505884d8341d81fa0a7ed2d9e1fc37439b6f4b7;p=clang [OpenCL] Fix atomic Builtins check for address spaces of non-atomic pointer If there are two pointers passed to an atomic Builtin, Clang doesn't allow the second (non-atomic) one to be qualified with an address space. Remove this restriction by recording the address space of passed pointers in atomics type diagnostics. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@256243 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index d5c80c9e20..949e8742f9 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -1801,8 +1801,17 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult, Ty = ByValType; else if (Form == Arithmetic) Ty = Context.getPointerDiffType(); - else - Ty = Context.getPointerType(ValType.getUnqualifiedType()); + else { + Expr *ValArg = TheCall->getArg(i); + unsigned AS = 0; + // Keep address space of non-atomic pointer type. + if (const PointerType *PtrTy = + ValArg->getType()->getAs()) { + AS = PtrTy->getPointeeType().getAddressSpace(); + } + Ty = Context.getPointerType( + Context.getAddrSpaceQualType(ValType.getUnqualifiedType(), AS)); + } break; case 2: // The third argument to compare_exchange / GNU exchange is a diff --git a/test/CodeGen/atomic-ops.c b/test/CodeGen/atomic-ops.c index 353f77c37b..1ebb2baa1a 100644 --- a/test/CodeGen/atomic-ops.c +++ b/test/CodeGen/atomic-ops.c @@ -1,10 +1,10 @@ -// RUN: %clang_cc1 %s -emit-llvm -o - -ffreestanding -triple=i686-apple-darwin9 | FileCheck %s +// RUN: %clang_cc1 %s -emit-llvm -o - -ffreestanding -ffake-address-space-map -triple=i686-apple-darwin9 | FileCheck %s // REQUIRES: x86-registered-target // Also test serialization of atomic operations here, to avoid duplicating the // test. -// RUN: %clang_cc1 %s -emit-pch -o %t -ffreestanding -triple=i686-apple-darwin9 -// RUN: %clang_cc1 %s -include-pch %t -ffreestanding -triple=i686-apple-darwin9 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -emit-pch -o %t -ffreestanding -ffake-address-space-map -triple=i686-apple-darwin9 +// RUN: %clang_cc1 %s -include-pch %t -ffreestanding -ffake-address-space-map -triple=i686-apple-darwin9 -emit-llvm -o - | FileCheck %s #ifndef ALREADY_INCLUDED #define ALREADY_INCLUDED @@ -155,6 +155,14 @@ _Bool fi4c(atomic_int *i) { return atomic_compare_exchange_strong(i, &cmp, 1); } +#define _AS1 __attribute__((address_space(1))) +_Bool fi4d(_Atomic(int) *i, int _AS1 *ptr2) { + // CHECK-LABEL: @fi4d( + // CHECK: [[EXPECTED:%[.0-9A-Z_a-z]+]] = load i32, i32 addrspace(1)* %{{[0-9]+}} + // CHECK: cmpxchg i32* %{{[0-9]+}}, i32 [[EXPECTED]], i32 %{{[0-9]+}} acquire acquire + return __c11_atomic_compare_exchange_strong(i, ptr2, 1, memory_order_acquire, memory_order_acquire); +} + float ff1(_Atomic(float) *d) { // CHECK-LABEL: @ff1 // CHECK: load atomic i32, i32* {{.*}} monotonic diff --git a/test/Sema/atomic-ops.c b/test/Sema/atomic-ops.c index 5f308be7b4..9a37ec2a38 100644 --- a/test/Sema/atomic-ops.c +++ b/test/Sema/atomic-ops.c @@ -85,6 +85,9 @@ _Static_assert(__atomic_always_lock_free(4, &i64), ""); _Static_assert(!__atomic_always_lock_free(8, &i32), ""); _Static_assert(__atomic_always_lock_free(8, &i64), ""); +#define _AS1 __attribute__((address_space(1))) +#define _AS2 __attribute__((address_space(2))) + void f(_Atomic(int) *i, const _Atomic(int) *ci, _Atomic(int*) *p, _Atomic(float) *d, int *I, const int *CI, @@ -190,6 +193,9 @@ void f(_Atomic(int) *i, const _Atomic(int) *ci, (void)__atomic_compare_exchange(CI, I, I, 0, memory_order_seq_cst, memory_order_seq_cst); // expected-error {{address argument to atomic operation must be a pointer to non-const type ('const int *' invalid)}} (void)__atomic_compare_exchange(I, CI, I, 0, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{passing 'const int *' to parameter of type 'int *' discards qualifiers}} + // Pointers to different address spaces are allowed. + _Bool cmpexch_10 = __c11_atomic_compare_exchange_strong((_Atomic int _AS1 *)0x308, (int _AS2 *)0x309, 1, memory_order_seq_cst, memory_order_seq_cst); + const volatile int flag_k = 0; volatile int flag = 0; (void)(int)__atomic_test_and_set(&flag_k, memory_order_seq_cst); // expected-warning {{passing 'const volatile int *' to parameter of type 'volatile void *'}}