yaxunl created this revision.
yaxunl added a reviewer: rjmccall.

Currently clang does not allow implicit cast of a pointer to a pointer type in 
different address space but allows C-style cast of a pointer to a pointer type 
in different address space. However, there is a bug in Sema causing incorrect 
Cast Expr in AST for the latter case, which in turn results in invalid LLVM IR 
in codegen.

This is because Sema::IsQualificationConversion returns true for a cast of 
pointer to a pointer type in different address space, which in turn allows a 
standard conversion and results in a cast expression with no op in AST.

This patch fixes that by let  Sema::IsQualificationConversion returns false for 
a cast of pointer to a pointer type in different address space, which in turn 
disallows standard conversion, implicit cast, and static cast. Finally it 
results in an reinterpret cast and correct conversion kind is set.


https://reviews.llvm.org/D49294

Files:
  lib/Sema/SemaCast.cpp
  lib/Sema/SemaOverload.cpp
  test/CodeGenCXX/address-space-cast.cpp


Index: test/CodeGenCXX/address-space-cast.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/address-space-cast.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -triple=amdgcn-amd-amdhsa -emit-llvm -o - | FileCheck %s
+
+#define __private__ __attribute__((address_space(5)))
+
+void func_pchar(__private__ char* x);
+
+void test(char *gen_ptr) {
+  // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+  // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
+  __private__ char* priv_ptr = (__private__ char*)gen_ptr;
+  
+  // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+  // CHECK-NEXT: call void @_Z10func_pcharPU3AS5c(i8 addrspace(5)* %[[cast]])
+  func_pchar((__private__ char*)gen_ptr);
+}
Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -3143,6 +3143,12 @@
       = PreviousToQualsIncludeConst && ToQuals.hasConst();
   }
 
+  // ToDo: Add more detailed control for implicit address space casting for
+  // OpenCL C++.
+  if (FromType.getAddressSpace() != ToType.getAddressSpace() &&
+      !getLangOpts().OpenCLCPlusPlus)
+    return false;
+
   // We are left with FromType and ToType being the pointee types
   // after unwrapping the original FromType and ToType the same number
   // of types. If we unwrapped any pointers, and if FromType and
Index: lib/Sema/SemaCast.cpp
===================================================================
--- lib/Sema/SemaCast.cpp
+++ lib/Sema/SemaCast.cpp
@@ -2163,6 +2163,13 @@
     } else {
       Kind = CK_BitCast;
     }
+  } else if (SrcType->isPointerType() && DestType->isPointerType() &&
+             SrcType->getAs<PointerType>()
+                     ->getPointeeType()
+                     .getAddressSpace() != DestType->getAs<PointerType>()
+                                               ->getPointeeType()
+                                               .getAddressSpace()) {
+    Kind = CK_AddressSpaceConversion;
   } else {
     Kind = CK_BitCast;
   }


Index: test/CodeGenCXX/address-space-cast.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/address-space-cast.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -triple=amdgcn-amd-amdhsa -emit-llvm -o - | FileCheck %s
+
+#define __private__ __attribute__((address_space(5)))
+
+void func_pchar(__private__ char* x);
+
+void test(char *gen_ptr) {
+  // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+  // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
+  __private__ char* priv_ptr = (__private__ char*)gen_ptr;
+  
+  // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
+  // CHECK-NEXT: call void @_Z10func_pcharPU3AS5c(i8 addrspace(5)* %[[cast]])
+  func_pchar((__private__ char*)gen_ptr);
+}
Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -3143,6 +3143,12 @@
       = PreviousToQualsIncludeConst && ToQuals.hasConst();
   }
 
+  // ToDo: Add more detailed control for implicit address space casting for
+  // OpenCL C++.
+  if (FromType.getAddressSpace() != ToType.getAddressSpace() &&
+      !getLangOpts().OpenCLCPlusPlus)
+    return false;
+
   // We are left with FromType and ToType being the pointee types
   // after unwrapping the original FromType and ToType the same number
   // of types. If we unwrapped any pointers, and if FromType and
Index: lib/Sema/SemaCast.cpp
===================================================================
--- lib/Sema/SemaCast.cpp
+++ lib/Sema/SemaCast.cpp
@@ -2163,6 +2163,13 @@
     } else {
       Kind = CK_BitCast;
     }
+  } else if (SrcType->isPointerType() && DestType->isPointerType() &&
+             SrcType->getAs<PointerType>()
+                     ->getPointeeType()
+                     .getAddressSpace() != DestType->getAs<PointerType>()
+                                               ->getPointeeType()
+                                               .getAddressSpace()) {
+    Kind = CK_AddressSpaceConversion;
   } else {
     Kind = CK_BitCast;
   }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to