Skip to content

Commit 25942d7

Browse files
committed
[AMDGPU] Allow relaxed/consume memory order for atomic inc/dec
Reviewed by: Jon Chesterfield Differential Revision: https://reviews.llvm.org/D100144
1 parent acf3279 commit 25942d7

File tree

4 files changed

+46
-20
lines changed

4 files changed

+46
-20
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15469,8 +15469,10 @@ bool CodeGenFunction::ProcessOrderScopeAMDGCN(Value *Order, Value *Scope,
1546915469
int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
1547015470

1547115471
// Map C11/C++11 memory ordering to LLVM memory ordering
15472+
assert(llvm::isValidAtomicOrderingCABI(ord));
1547215473
switch (static_cast<llvm::AtomicOrderingCABI>(ord)) {
1547315474
case llvm::AtomicOrderingCABI::acquire:
15475+
case llvm::AtomicOrderingCABI::consume:
1547415476
AO = llvm::AtomicOrdering::Acquire;
1547515477
break;
1547615478
case llvm::AtomicOrderingCABI::release:
@@ -15482,8 +15484,8 @@ bool CodeGenFunction::ProcessOrderScopeAMDGCN(Value *Order, Value *Scope,
1548215484
case llvm::AtomicOrderingCABI::seq_cst:
1548315485
AO = llvm::AtomicOrdering::SequentiallyConsistent;
1548415486
break;
15485-
case llvm::AtomicOrderingCABI::consume:
1548615487
case llvm::AtomicOrderingCABI::relaxed:
15488+
AO = llvm::AtomicOrdering::Monotonic;
1548715489
break;
1548815490
}
1548915491

clang/lib/Sema/SemaChecking.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3384,20 +3384,28 @@ bool Sema::CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID,
33843384
if (!ArgExpr->EvaluateAsInt(ArgResult, Context))
33853385
return Diag(ArgExpr->getExprLoc(), diag::err_typecheck_expect_int)
33863386
<< ArgExpr->getType();
3387-
int ord = ArgResult.Val.getInt().getZExtValue();
3387+
auto Ord = ArgResult.Val.getInt().getZExtValue();
33883388

33893389
// Check valididty of memory ordering as per C11 / C++11's memody model.
3390-
switch (static_cast<llvm::AtomicOrderingCABI>(ord)) {
3390+
// Only fence needs check. Atomic dec/inc allow all memory orders.
3391+
auto DiagInvalidMemOrder = [&](auto *ArgExpr) {
3392+
return Diag(ArgExpr->getBeginLoc(),
3393+
diag::warn_atomic_op_has_invalid_memory_order)
3394+
<< ArgExpr->getSourceRange();
3395+
};
3396+
if (!llvm::isValidAtomicOrderingCABI(Ord))
3397+
return DiagInvalidMemOrder(ArgExpr);
3398+
switch (static_cast<llvm::AtomicOrderingCABI>(Ord)) {
3399+
case llvm::AtomicOrderingCABI::relaxed:
3400+
case llvm::AtomicOrderingCABI::consume:
3401+
if (BuiltinID == AMDGPU::BI__builtin_amdgcn_fence)
3402+
return DiagInvalidMemOrder(ArgExpr);
3403+
break;
33913404
case llvm::AtomicOrderingCABI::acquire:
33923405
case llvm::AtomicOrderingCABI::release:
33933406
case llvm::AtomicOrderingCABI::acq_rel:
33943407
case llvm::AtomicOrderingCABI::seq_cst:
33953408
break;
3396-
default: {
3397-
return Diag(ArgExpr->getBeginLoc(),
3398-
diag::warn_atomic_op_has_invalid_memory_order)
3399-
<< ArgExpr->getSourceRange();
3400-
}
34013409
}
34023410

34033411
Arg = TheCall->getArg(ScopeIndex);

clang/test/CodeGenCXX/builtin-amdgcn-atomic-inc-dec.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -188,33 +188,45 @@ __attribute__((device)) void test_order32() {
188188
// CHECK-LABEL: test_order32
189189
__attribute__((shared)) __UINT32_TYPE__ val;
190190

191-
// CHECK: %1 = call i32 @llvm.amdgcn.atomic.inc.i32.p0i32(i32* addrspacecast (i32 addrspace(3)* @_ZZ12test_order32vE3val to i32*), i32 %0, i32 4, i32 2, i1 false)
191+
// CHECK: call i32 @llvm.amdgcn.atomic.inc.i32.p0i32(i32* addrspacecast (i32 addrspace(3)* @_ZZ12test_order32vE3val to i32*), i32 {{.*}}, i32 2, i32 2, i1 false)
192+
val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_RELAXED, "workgroup");
193+
194+
// CHECK: call i32 @llvm.amdgcn.atomic.inc.i32.p0i32(i32* addrspacecast (i32 addrspace(3)* @_ZZ12test_order32vE3val to i32*), i32 {{.*}}, i32 4, i32 2, i1 false)
195+
val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_CONSUME, "workgroup");
196+
197+
// CHECK: call i32 @llvm.amdgcn.atomic.inc.i32.p0i32(i32* addrspacecast (i32 addrspace(3)* @_ZZ12test_order32vE3val to i32*), i32 {{.*}}, i32 4, i32 2, i1 false)
192198
val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_ACQUIRE, "workgroup");
193199

194-
// CHECK: %3 = call i32 @llvm.amdgcn.atomic.dec.i32.p0i32(i32* addrspacecast (i32 addrspace(3)* @_ZZ12test_order32vE3val to i32*), i32 %2, i32 5, i32 2, i1 false)
200+
// CHECK: call i32 @llvm.amdgcn.atomic.dec.i32.p0i32(i32* addrspacecast (i32 addrspace(3)* @_ZZ12test_order32vE3val to i32*), i32 {{.*}}, i32 5, i32 2, i1 false)
195201
val = __builtin_amdgcn_atomic_dec32(&val, val, __ATOMIC_RELEASE, "workgroup");
196202

197-
// CHECK: %5 = call i32 @llvm.amdgcn.atomic.dec.i32.p0i32(i32* addrspacecast (i32 addrspace(3)* @_ZZ12test_order32vE3val to i32*), i32 %4, i32 6, i32 2, i1 false)
203+
// CHECK: call i32 @llvm.amdgcn.atomic.dec.i32.p0i32(i32* addrspacecast (i32 addrspace(3)* @_ZZ12test_order32vE3val to i32*), i32 {{.*}}, i32 6, i32 2, i1 false)
198204
val = __builtin_amdgcn_atomic_dec32(&val, val, __ATOMIC_ACQ_REL, "workgroup");
199205

200-
// CHECK: %7 = call i32 @llvm.amdgcn.atomic.dec.i32.p0i32(i32* addrspacecast (i32 addrspace(3)* @_ZZ12test_order32vE3val to i32*), i32 %6, i32 7, i32 2, i1 false)
206+
// CHECK: call i32 @llvm.amdgcn.atomic.dec.i32.p0i32(i32* addrspacecast (i32 addrspace(3)* @_ZZ12test_order32vE3val to i32*), i32 {{.*}}, i32 7, i32 2, i1 false)
201207
val = __builtin_amdgcn_atomic_dec32(&val, val, __ATOMIC_SEQ_CST, "workgroup");
202208
}
203209

204210
__attribute__((device)) void test_order64() {
205211
// CHECK-LABEL: test_order64
206212
__attribute__((shared)) __UINT64_TYPE__ val;
207213

208-
// CHECK: %1 = call i64 @llvm.amdgcn.atomic.inc.i64.p0i64(i64* addrspacecast (i64 addrspace(3)* @_ZZ12test_order64vE3val to i64*), i64 %0, i32 4, i32 2, i1 false)
214+
// CHECK: call i64 @llvm.amdgcn.atomic.inc.i64.p0i64(i64* addrspacecast (i64 addrspace(3)* @_ZZ12test_order64vE3val to i64*), i64 {{.*}}, i32 2, i32 2, i1 false)
215+
val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_RELAXED, "workgroup");
216+
217+
// CHECK: call i64 @llvm.amdgcn.atomic.dec.i64.p0i64(i64* addrspacecast (i64 addrspace(3)* @_ZZ12test_order64vE3val to i64*), i64 {{.*}}, i32 4, i32 2, i1 false)
218+
val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_CONSUME, "workgroup");
219+
220+
// CHECK: call i64 @llvm.amdgcn.atomic.inc.i64.p0i64(i64* addrspacecast (i64 addrspace(3)* @_ZZ12test_order64vE3val to i64*), i64 {{.*}}, i32 4, i32 2, i1 false)
209221
val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_ACQUIRE, "workgroup");
210222

211-
// CHECK: %3 = call i64 @llvm.amdgcn.atomic.dec.i64.p0i64(i64* addrspacecast (i64 addrspace(3)* @_ZZ12test_order64vE3val to i64*), i64 %2, i32 5, i32 2, i1 false)
223+
// CHECK: call i64 @llvm.amdgcn.atomic.dec.i64.p0i64(i64* addrspacecast (i64 addrspace(3)* @_ZZ12test_order64vE3val to i64*), i64 {{.*}}, i32 5, i32 2, i1 false)
212224
val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_RELEASE, "workgroup");
213225

214-
// CHECK: %5 = call i64 @llvm.amdgcn.atomic.dec.i64.p0i64(i64* addrspacecast (i64 addrspace(3)* @_ZZ12test_order64vE3val to i64*), i64 %4, i32 6, i32 2, i1 false)
226+
// CHECK: call i64 @llvm.amdgcn.atomic.dec.i64.p0i64(i64* addrspacecast (i64 addrspace(3)* @_ZZ12test_order64vE3val to i64*), i64 {{.*}}, i32 6, i32 2, i1 false)
215227
val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_ACQ_REL, "workgroup");
216228

217-
// CHECK: %7 = call i64 @llvm.amdgcn.atomic.dec.i64.p0i64(i64* addrspacecast (i64 addrspace(3)* @_ZZ12test_order64vE3val to i64*), i64 %6, i32 7, i32 2, i1 false)
229+
// CHECK: call i64 @llvm.amdgcn.atomic.dec.i64.p0i64(i64* addrspacecast (i64 addrspace(3)* @_ZZ12test_order64vE3val to i64*), i64 {{.*}}, i32 7, i32 2, i1 false)
218230
val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_SEQ_CST, "workgroup");
219231
}
220232

clang/test/SemaOpenCL/builtins-amdgcn-error.cl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ void test_s_setreg(int x, int y) {
148148
void test_atomic_inc32() {
149149
uint val = 17;
150150
val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_SEQ_CST + 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}}
151-
val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_ACQUIRE - 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}}
151+
val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_RELAXED, "workgroup");
152+
val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_CONSUME, "workgroup");
152153
val = __builtin_amdgcn_atomic_inc32(4); // expected-error {{too few arguments to function call, expected 4}}
153154
val = __builtin_amdgcn_atomic_inc32(&val, val, 4, 4, 4, 4); // expected-error {{too many arguments to function call, expected 4}}
154155
val = __builtin_amdgcn_atomic_inc32(&val, val, 3.14, ""); // expected-warning {{implicit conversion from 'double' to 'unsigned int' changes value from 3.14 to 3}}
@@ -162,7 +163,8 @@ void test_atomic_inc32() {
162163
void test_atomic_inc64() {
163164
__UINT64_TYPE__ val = 17;
164165
val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_SEQ_CST + 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}}
165-
val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_ACQUIRE - 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}}
166+
val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_RELAXED, "workgroup");
167+
val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_CONSUME, "workgroup");
166168
val = __builtin_amdgcn_atomic_inc64(4); // expected-error {{too few arguments to function call, expected 4}}
167169
val = __builtin_amdgcn_atomic_inc64(&val, val, 4, 4, 4, 4); // expected-error {{too many arguments to function call, expected 4}}
168170
val = __builtin_amdgcn_atomic_inc64(&val, val, 3.14, ""); // expected-warning {{implicit conversion from 'double' to 'unsigned int' changes value from 3.14 to 3}}
@@ -176,7 +178,8 @@ void test_atomic_inc64() {
176178
void test_atomic_dec32() {
177179
uint val = 17;
178180
val = __builtin_amdgcn_atomic_dec32(&val, val, __ATOMIC_SEQ_CST + 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}}
179-
val = __builtin_amdgcn_atomic_dec32(&val, val, __ATOMIC_ACQUIRE - 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}}
181+
val = __builtin_amdgcn_atomic_dec32(&val, val, __ATOMIC_RELAXED, "workgroup");
182+
val = __builtin_amdgcn_atomic_dec32(&val, val, __ATOMIC_CONSUME, "workgroup");
180183
val = __builtin_amdgcn_atomic_dec32(4); // expected-error {{too few arguments to function call, expected 4}}
181184
val = __builtin_amdgcn_atomic_dec32(&val, val, 4, 4, 4, 4); // expected-error {{too many arguments to function call, expected 4}}
182185
val = __builtin_amdgcn_atomic_dec32(&val, val, 3.14, ""); // expected-warning {{implicit conversion from 'double' to 'unsigned int' changes value from 3.14 to 3}}
@@ -190,7 +193,8 @@ void test_atomic_dec32() {
190193
void test_atomic_dec64() {
191194
__UINT64_TYPE__ val = 17;
192195
val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_SEQ_CST + 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}}
193-
val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_ACQUIRE - 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}}
196+
val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_RELAXED, "workgroup");
197+
val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_CONSUME, "workgroup");
194198
val = __builtin_amdgcn_atomic_dec64(4); // expected-error {{too few arguments to function call, expected 4}}
195199
val = __builtin_amdgcn_atomic_dec64(&val, val, 4, 4, 4, 4); // expected-error {{too many arguments to function call, expected 4}}
196200
val = __builtin_amdgcn_atomic_dec64(&val, val, 3.14, ""); // expected-warning {{implicit conversion from 'double' to 'unsigned int' changes value from 3.14 to 3}}

0 commit comments

Comments
 (0)