[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. llvm-svn: 256243
This commit is contained in:
parent
a108010385
commit
76fd1052fd
|
@ -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<PointerType>()) {
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 *'}}
|
||||
|
|
Loading…
Reference in New Issue