[clang] 0882c9d - [AMDGPU] Change Clang AMDGCN atomic inc/dec builtins to take unsigned values

Saiyedul Islam via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 6 23:37:20 PDT 2020


Author: Saiyedul Islam
Date: 2020-07-07T06:36:25Z
New Revision: 0882c9d4fc49858338c9655154f1ad8357a8e516

URL: https://github.com/llvm/llvm-project/commit/0882c9d4fc49858338c9655154f1ad8357a8e516
DIFF: https://github.com/llvm/llvm-project/commit/0882c9d4fc49858338c9655154f1ad8357a8e516.diff

LOG: [AMDGPU] Change Clang AMDGCN atomic inc/dec builtins to take unsigned values

builtin_amdgcn_atomic_inc32(uint *Ptr, uint Val, unsigned MemoryOrdering, const char *SyncScope)
builtin_amdgcn_atomic_inc64(uint64_t *Ptr, uint64_t Val, unsigned MemoryOrdering, const char *SyncScope)
builtin_amdgcn_atomic_dec32(uint *Ptr, uint Val, unsigned MemoryOrdering, const char *SyncScope)
builtin_amdgcn_atomic_dec64(uint64_t *Ptr, uint64_t Val, unsigned MemoryOrdering, const char *SyncScope)

As AMDGCN IR instrinsic for atomic inc/dec does unsigned comparison,
these clang builtins should also take unsigned types instead of signed
int types.

Reviewed By: JonChesterfield

Differential Revision: https://reviews.llvm.org/D83121

Added: 
    

Modified: 
    clang/include/clang/Basic/BuiltinsAMDGPU.def
    clang/test/CodeGenCXX/builtin-amdgcn-atomic-inc-dec.cpp
    clang/test/Sema/builtin-amdgcn-atomic-inc-dec-failure.cpp
    clang/test/SemaOpenCL/builtins-amdgcn-error.cl

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/BuiltinsAMDGPU.def b/clang/include/clang/Basic/BuiltinsAMDGPU.def
index 60be0525fabc..042a86368559 100644
--- a/clang/include/clang/Basic/BuiltinsAMDGPU.def
+++ b/clang/include/clang/Basic/BuiltinsAMDGPU.def
@@ -60,11 +60,11 @@ BUILTIN(__builtin_amdgcn_ds_gws_sema_br, "vUiUi", "n")
 BUILTIN(__builtin_amdgcn_ds_gws_sema_p, "vUi", "n")
 BUILTIN(__builtin_amdgcn_fence, "vUicC*", "n")
 
-BUILTIN(__builtin_amdgcn_atomic_inc32, "ZiZiD*ZiUicC*", "n")
-BUILTIN(__builtin_amdgcn_atomic_inc64, "WiWiD*WiUicC*", "n")
+BUILTIN(__builtin_amdgcn_atomic_inc32, "UZiUZiD*UZiUicC*", "n")
+BUILTIN(__builtin_amdgcn_atomic_inc64, "UWiUWiD*UWiUicC*", "n")
 
-BUILTIN(__builtin_amdgcn_atomic_dec32, "ZiZiD*ZiUicC*", "n")
-BUILTIN(__builtin_amdgcn_atomic_dec64, "WiWiD*WiUicC*", "n")
+BUILTIN(__builtin_amdgcn_atomic_dec32, "UZiUZiD*UZiUicC*", "n")
+BUILTIN(__builtin_amdgcn_atomic_dec64, "UWiUWiD*UWiUicC*", "n")
 
 // FIXME: Need to disallow constant address space.
 BUILTIN(__builtin_amdgcn_div_scale, "dddbb*", "n")

diff  --git a/clang/test/CodeGenCXX/builtin-amdgcn-atomic-inc-dec.cpp b/clang/test/CodeGenCXX/builtin-amdgcn-atomic-inc-dec.cpp
index 535c3d754954..77ea3d485c8a 100644
--- a/clang/test/CodeGenCXX/builtin-amdgcn-atomic-inc-dec.cpp
+++ b/clang/test/CodeGenCXX/builtin-amdgcn-atomic-inc-dec.cpp
@@ -2,9 +2,9 @@
 // RUN: %clang_cc1 %s -x hip -fcuda-is-device -emit-llvm -O0 -o - \
 // RUN:   -triple=amdgcn-amd-amdhsa  | opt -S | FileCheck %s
 
-__attribute__((device)) void test_non_volatile_parameter32(int *ptr) {
+__attribute__((device)) void test_non_volatile_parameter32(__UINT32_TYPE__ *ptr) {
   // CHECK-LABEL: test_non_volatile_parameter32
-  int res;
+  __UINT32_TYPE__ res;
   // CHECK: %ptr.addr = alloca i32*, align 8, addrspace(5)
   // CHECK-NEXT: %ptr.addr.ascast = addrspacecast i32* addrspace(5)* %ptr.addr to i32**
   // CHECK-NEXT: %res = alloca i32, align 4, addrspace(5)
@@ -25,9 +25,9 @@ __attribute__((device)) void test_non_volatile_parameter32(int *ptr) {
   res = __builtin_amdgcn_atomic_dec32(ptr, *ptr, __ATOMIC_SEQ_CST, "workgroup");
 }
 
-__attribute__((device)) void test_non_volatile_parameter64(__INT64_TYPE__ *ptr) {
+__attribute__((device)) void test_non_volatile_parameter64(__UINT64_TYPE__ *ptr) {
   // CHECK-LABEL: test_non_volatile_parameter64
-  __INT64_TYPE__ res;
+  __UINT64_TYPE__ res;
   // CHECK: %ptr.addr = alloca i64*, align 8, addrspace(5)
   // CHECK-NEXT: %ptr.addr.ascast = addrspacecast i64* addrspace(5)* %ptr.addr to i64**
   // CHECK-NEXT: %res = alloca i64, align 8, addrspace(5)
@@ -48,9 +48,9 @@ __attribute__((device)) void test_non_volatile_parameter64(__INT64_TYPE__ *ptr)
   res = __builtin_amdgcn_atomic_dec64(ptr, *ptr, __ATOMIC_SEQ_CST, "workgroup");
 }
 
-__attribute__((device)) void test_volatile_parameter32(volatile int *ptr) {
+__attribute__((device)) void test_volatile_parameter32(volatile __UINT32_TYPE__ *ptr) {
   // CHECK-LABEL: test_volatile_parameter32
-  int res;
+  __UINT32_TYPE__ res;
   // CHECK: %ptr.addr = alloca i32*, align 8, addrspace(5)
   // CHECK-NEXT: %ptr.addr.ascast = addrspacecast i32* addrspace(5)* %ptr.addr to i32**
   // CHECK-NEXT: %res = alloca i32, align 4, addrspace(5)
@@ -71,9 +71,9 @@ __attribute__((device)) void test_volatile_parameter32(volatile int *ptr) {
   res = __builtin_amdgcn_atomic_dec32(ptr, *ptr, __ATOMIC_SEQ_CST, "workgroup");
 }
 
-__attribute__((device)) void test_volatile_parameter64(volatile __INT64_TYPE__ *ptr) {
+__attribute__((device)) void test_volatile_parameter64(volatile __UINT64_TYPE__ *ptr) {
   // CHECK-LABEL: test_volatile_parameter64
-  __INT64_TYPE__ res;
+  __UINT64_TYPE__ res;
   // CHECK: %ptr.addr = alloca i64*, align 8, addrspace(5)
   // CHECK-NEXT: %ptr.addr.ascast = addrspacecast i64* addrspace(5)* %ptr.addr to i64**
   // CHECK-NEXT: %res = alloca i64, align 8, addrspace(5)
@@ -96,7 +96,7 @@ __attribute__((device)) void test_volatile_parameter64(volatile __INT64_TYPE__ *
 
 __attribute__((device)) void test_shared32() {
   // CHECK-LABEL: test_shared32
-  __attribute__((shared)) int val;
+  __attribute__((shared)) __UINT32_TYPE__ val;
 
   // CHECK: %0 = load i32, i32* addrspacecast (i32 addrspace(3)* @_ZZ13test_shared32vE3val to i32*), align 4
   // CHECK-NEXT: %1 = call i32 @llvm.amdgcn.atomic.inc.i32.p0i32(i32* addrspacecast (i32 addrspace(3)* @_ZZ13test_shared32vE3val to i32*), i32 %0, i32 7, i32 2, i1 false)
@@ -111,7 +111,7 @@ __attribute__((device)) void test_shared32() {
 
 __attribute__((device)) void test_shared64() {
   // CHECK-LABEL: test_shared64
-  __attribute__((shared)) __INT64_TYPE__ val;
+  __attribute__((shared)) __UINT64_TYPE__ val;
 
   // CHECK: %0 = load i64, i64* addrspacecast (i64 addrspace(3)* @_ZZ13test_shared64vE3val to i64*), align 8
   // CHECK-NEXT: %1 = call i64 @llvm.amdgcn.atomic.inc.i64.p0i64(i64* addrspacecast (i64 addrspace(3)* @_ZZ13test_shared64vE3val to i64*), i64 %0, i32 7, i32 2, i1 false)
@@ -124,7 +124,7 @@ __attribute__((device)) void test_shared64() {
   val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_SEQ_CST, "workgroup");
 }
 
-int global_val32;
+__UINT32_TYPE__ global_val32;
 __attribute__((device)) void test_global32() {
   // CHECK-LABEL: test_global32
   // CHECK: %0 = load i32, i32* addrspacecast (i32 addrspace(1)* @global_val32 to i32*), align 4
@@ -138,7 +138,7 @@ __attribute__((device)) void test_global32() {
   global_val32 = __builtin_amdgcn_atomic_dec32(&global_val32, global_val32, __ATOMIC_SEQ_CST, "workgroup");
 }
 
-__INT64_TYPE__ global_val64;
+__UINT64_TYPE__ global_val64;
 __attribute__((device)) void test_global64() {
   // CHECK-LABEL: test_global64
   // CHECK: %0 = load i64, i64* addrspacecast (i64 addrspace(1)* @global_val64 to i64*), align 8
@@ -152,10 +152,10 @@ __attribute__((device)) void test_global64() {
   global_val64 = __builtin_amdgcn_atomic_dec64(&global_val64, global_val64, __ATOMIC_SEQ_CST, "workgroup");
 }
 
-__attribute__((constant)) int cval32;
+__attribute__((constant)) __UINT32_TYPE__ cval32;
 __attribute__((device)) void test_constant32() {
   // CHECK-LABEL: test_constant32
-  int local_val;
+  __UINT32_TYPE__ local_val;
 
   // CHECK: %0 = load i32, i32* addrspacecast (i32 addrspace(4)* @cval32 to i32*), align 4
   // CHECK-NEXT: %1 = call i32 @llvm.amdgcn.atomic.inc.i32.p0i32(i32* addrspacecast (i32 addrspace(4)* @cval32 to i32*), i32 %0, i32 7, i32 2, i1 false)
@@ -168,10 +168,10 @@ __attribute__((device)) void test_constant32() {
   local_val = __builtin_amdgcn_atomic_dec32(&cval32, cval32, __ATOMIC_SEQ_CST, "workgroup");
 }
 
-__attribute__((constant)) __INT64_TYPE__ cval64;
+__attribute__((constant)) __UINT64_TYPE__ cval64;
 __attribute__((device)) void test_constant64() {
   // CHECK-LABEL: test_constant64
-  __INT64_TYPE__ local_val;
+  __UINT64_TYPE__ local_val;
 
   // CHECK: %0 = load i64, i64* addrspacecast (i64 addrspace(4)* @cval64 to i64*), align 8
   // CHECK-NEXT: %1 = call i64 @llvm.amdgcn.atomic.inc.i64.p0i64(i64* addrspacecast (i64 addrspace(4)* @cval64 to i64*), i64 %0, i32 7, i32 2, i1 false)
@@ -186,7 +186,7 @@ __attribute__((device)) void test_constant64() {
 
 __attribute__((device)) void test_order32() {
   // CHECK-LABEL: test_order32
-  __attribute__((shared)) int val;
+  __attribute__((shared)) __UINT32_TYPE__ val;
 
   // 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)
   val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_ACQUIRE, "workgroup");
@@ -203,7 +203,7 @@ __attribute__((device)) void test_order32() {
 
 __attribute__((device)) void test_order64() {
   // CHECK-LABEL: test_order64
-  __attribute__((shared)) __INT64_TYPE__ val;
+  __attribute__((shared)) __UINT64_TYPE__ val;
 
   // 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)
   val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_ACQUIRE, "workgroup");
@@ -220,7 +220,7 @@ __attribute__((device)) void test_order64() {
 
 __attribute__((device)) void test_scope32() {
   // CHECK-LABEL: test_scope32
-  __attribute__((shared)) int val;
+  __attribute__((shared)) __UINT32_TYPE__ val;
 
   // CHECK: %1 = call i32 @llvm.amdgcn.atomic.inc.i32.p0i32(i32* addrspacecast (i32 addrspace(3)* @_ZZ12test_scope32vE3val to i32*), i32 %0, i32 7, i32 1, i1 false)
   val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_SEQ_CST, "");
@@ -237,7 +237,7 @@ __attribute__((device)) void test_scope32() {
 
 __attribute__((device)) void test_scope64() {
   // CHECK-LABEL: test_scope64
-  __attribute__((shared)) __INT64_TYPE__ val;
+  __attribute__((shared)) __UINT64_TYPE__ val;
 
   // CHECK: %1 = call i64 @llvm.amdgcn.atomic.inc.i64.p0i64(i64* addrspacecast (i64 addrspace(3)* @_ZZ12test_scope64vE3val to i64*), i64 %0, i32 7, i32 1, i1 false)
   val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_SEQ_CST, "");

diff  --git a/clang/test/Sema/builtin-amdgcn-atomic-inc-dec-failure.cpp b/clang/test/Sema/builtin-amdgcn-atomic-inc-dec-failure.cpp
index c08b00bac0cf..9351b4ecb032 100644
--- a/clang/test/Sema/builtin-amdgcn-atomic-inc-dec-failure.cpp
+++ b/clang/test/Sema/builtin-amdgcn-atomic-inc-dec-failure.cpp
@@ -2,17 +2,18 @@
 // RUN: not %clang_cc1 %s -x hip -fcuda-is-device -o - -emit-llvm -triple=amdgcn-amd-amdhsa 2>&1 | FileCheck %s
 
 void test_host() {
-  int val;
+  __UINT32_TYPE__ val32;
+  __UINT64_TYPE__ val64;
 
   // CHECK: error: reference to __device__ function '__builtin_amdgcn_atomic_inc32' in __host__ function
-  val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_SEQ_CST, "");
+  val32 = __builtin_amdgcn_atomic_inc32(&val32, val32, __ATOMIC_SEQ_CST, "");
 
   // CHECK: error: reference to __device__ function '__builtin_amdgcn_atomic_inc64' in __host__ function
-  val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_SEQ_CST, "");
+  val64 = __builtin_amdgcn_atomic_inc64(&val64, val64, __ATOMIC_SEQ_CST, "");
 
   // CHECK: error: reference to __device__ function '__builtin_amdgcn_atomic_dec32' in __host__ function
-  val = __builtin_amdgcn_atomic_dec32(&val, val, __ATOMIC_SEQ_CST, "");
+  val32 = __builtin_amdgcn_atomic_dec32(&val32, val32, __ATOMIC_SEQ_CST, "");
 
   // CHECK: error: reference to __device__ function '__builtin_amdgcn_atomic_dec64' in __host__ function
-  val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_SEQ_CST, "");
+  val64 = __builtin_amdgcn_atomic_dec64(&val64, val64, __ATOMIC_SEQ_CST, "");
 }

diff  --git a/clang/test/SemaOpenCL/builtins-amdgcn-error.cl b/clang/test/SemaOpenCL/builtins-amdgcn-error.cl
index e2d9082f8f72..8001cf3b59e0 100644
--- a/clang/test/SemaOpenCL/builtins-amdgcn-error.cl
+++ b/clang/test/SemaOpenCL/builtins-amdgcn-error.cl
@@ -146,7 +146,7 @@ void test_s_setreg(int x, int y) {
 }
 
 void test_atomic_inc32() {
-  int val = 17;
+  uint val = 17;
   val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_SEQ_CST + 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}}
   val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_ACQUIRE - 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}}
   val = __builtin_amdgcn_atomic_inc32(4);                                            // expected-error {{too few arguments to function call, expected 4}}
@@ -155,10 +155,12 @@ void test_atomic_inc32() {
   val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_ACQUIRE, 5);               // expected-warning {{incompatible integer to pointer conversion passing 'int' to parameter of type 'const char *'}}
   const char ptr[] = "workgroup";
   val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_ACQUIRE, ptr); // expected-error {{expression is not a string literal}}
+  int signedVal = 15;
+  signedVal = __builtin_amdgcn_atomic_inc32(&signedVal, signedVal, __ATOMIC_ACQUIRE, ""); // expected-warning {{passing '__private int *' to parameter of type 'volatile __private unsigned int *' converts between pointers to integer types with 
diff erent sign}}
 }
 
 void test_atomic_inc64() {
-  __INT64_TYPE__ val = 17;
+  __UINT64_TYPE__ val = 17;
   val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_SEQ_CST + 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}}
   val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_ACQUIRE - 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}}
   val = __builtin_amdgcn_atomic_inc64(4);                                            // expected-error {{too few arguments to function call, expected 4}}
@@ -167,10 +169,12 @@ void test_atomic_inc64() {
   val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_ACQUIRE, 5);               // expected-warning {{incompatible integer to pointer conversion passing 'int' to parameter of type 'const char *'}}
   const char ptr[] = "workgroup";
   val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_ACQUIRE, ptr); // expected-error {{expression is not a string literal}}
+  __INT64_TYPE__ signedVal = 15;
+  signedVal = __builtin_amdgcn_atomic_inc64(&signedVal, signedVal, __ATOMIC_ACQUIRE, ""); // expected-warning {{passing '__private long *' to parameter of type 'volatile __private unsigned long *' converts between pointers to integer types with 
diff erent sign}}
 }
 
 void test_atomic_dec32() {
-  int val = 17;
+  uint val = 17;
   val = __builtin_amdgcn_atomic_dec32(&val, val, __ATOMIC_SEQ_CST + 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}}
   val = __builtin_amdgcn_atomic_dec32(&val, val, __ATOMIC_ACQUIRE - 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}}
   val = __builtin_amdgcn_atomic_dec32(4);                                            // expected-error {{too few arguments to function call, expected 4}}
@@ -179,10 +183,12 @@ void test_atomic_dec32() {
   val = __builtin_amdgcn_atomic_dec32(&val, val, __ATOMIC_ACQUIRE, 5);               // expected-warning {{incompatible integer to pointer conversion passing 'int' to parameter of type 'const char *'}}
   const char ptr[] = "workgroup";
   val = __builtin_amdgcn_atomic_dec32(&val, val, __ATOMIC_ACQUIRE, ptr); // expected-error {{expression is not a string literal}}
+  int signedVal = 15;
+  signedVal = __builtin_amdgcn_atomic_dec32(&signedVal, signedVal, __ATOMIC_ACQUIRE, ""); // expected-warning {{passing '__private int *' to parameter of type 'volatile __private unsigned int *' converts between pointers to integer types with 
diff erent sign}}
 }
 
 void test_atomic_dec64() {
-  __INT64_TYPE__ val = 17;
+  __UINT64_TYPE__ val = 17;
   val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_SEQ_CST + 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}}
   val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_ACQUIRE - 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}}
   val = __builtin_amdgcn_atomic_dec64(4);                                            // expected-error {{too few arguments to function call, expected 4}}
@@ -191,4 +197,6 @@ void test_atomic_dec64() {
   val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_ACQUIRE, 5);               // expected-warning {{incompatible integer to pointer conversion passing 'int' to parameter of type 'const char *'}}
   const char ptr[] = "workgroup";
   val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_ACQUIRE, ptr); // expected-error {{expression is not a string literal}}
+  __INT64_TYPE__ signedVal = 15;
+  signedVal = __builtin_amdgcn_atomic_dec64(&signedVal, signedVal, __ATOMIC_ACQUIRE, ""); // expected-warning {{passing '__private long *' to parameter of type 'volatile __private unsigned long *' converts between pointers to integer types with 
diff erent sign}}
 }


        


More information about the cfe-commits mailing list