Hi jholewinski, rjmccall,

Here a small patch that fixes the CUDA code generator handling implicit address 
space conversions. In CUDA address spaces at sema level are attributes for the 
variable declaration, making my previous patch on casts not effective. In such 
cases we must generate some addrspacecast.

The specific test cases were provided by Jeroen Ketama.

http://llvm-reviews.chandlerc.com/D2462

Files:
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenFunction.h
  test/CodeGenCUDA/address-spaces-implicit-conversion.cu

Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -2430,7 +2430,7 @@
         // can happen due to trivial type mismatches.
         if (IRArgNo < IRFuncTy->getNumParams() &&
             V->getType() != IRFuncTy->getParamType(IRArgNo))
-          V = Builder.CreateBitCast(V, IRFuncTy->getParamType(IRArgNo));
+          V = EmitImplicitTypeCoercion(V, IRFuncTy->getParamType(IRArgNo));
         Args.push_back(V);
         
         checkArgMatches(V, IRArgNo, IRFuncTy);
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -1432,6 +1432,13 @@
   }
 
   assert(Src.isScalar() && "Can't emit an agg store with this method");
+
+  // Handle CUDA implicit address space conversions.
+  if (getLangOpts().CUDA)
+    if (Src.getScalarVal()->getType()->isPtrOrPtrVectorTy())
+      Src = RValue::get(EmitBitCastOrAddrSpaceCast(Src.getScalarVal(),
+                                                   
ConvertType(Dst.getType())));
+
   EmitStoreOfScalar(Src.getScalarVal(), Dst, isInit);
 }
 
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -1499,3 +1499,21 @@
 }
 
 CodeGenFunction::CGCapturedStmtInfo::~CGCapturedStmtInfo() { }
+
+llvm::Value *CodeGenFunction::EmitBitCastOrAddrSpaceCast(llvm::Value *V,
+                                                         llvm::Type *Ty) {
+  if (V->getType()->isPtrOrPtrVectorTy() && Ty->isPtrOrPtrVectorTy() &&
+      V->getType()->getPointerAddressSpace() != Ty->getPointerAddressSpace())
+    return Builder.CreateAddrSpaceCast(V, Ty);
+
+  return Builder.CreateBitCast(V, Ty);
+}
+
+llvm::Value *CodeGenFunction::EmitImplicitTypeCoercion(llvm::Value *V,
+                                                       llvm::Type *Ty) {
+  // Handle implicit pointer address space conversion for CUDA.
+  if (getLangOpts().CUDA)
+    return EmitBitCastOrAddrSpaceCast(V, Ty);
+
+  return Builder.CreateBitCast(V, Ty);
+}
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -2369,6 +2369,9 @@
 
   RValue EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest = 0);
 
+  llvm::Value *EmitImplicitTypeCoercion(llvm::Value *V, llvm::Type *Ty);
+  llvm::Value *EmitBitCastOrAddrSpaceCast(llvm::Value *V, llvm::Type *Ty);
+
   
//===--------------------------------------------------------------------===//
   //                         Annotations Emission
   
//===--------------------------------------------------------------------===//
Index: test/CodeGenCUDA/address-spaces-implicit-conversion.cu
===================================================================
--- test/CodeGenCUDA/address-spaces-implicit-conversion.cu
+++ test/CodeGenCUDA/address-spaces-implicit-conversion.cu
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -fcuda-is-device -triple 
nvptx-unknown-unknown | FileCheck %s
+
+#include "../SemaCUDA/cuda.h"
+
+
+__device__ void bar(int &x) {
+  // CHECK: bar
+  x = 0;
+}
+
+int x;
+
+__global__ void implicit_as_cast_from_shared_scalar() {
+  // CHECK: implicit_as_cast_from_shared_scalar
+  __shared__ int b;
+  int &y = b;
+  // CHECK: addrspacecast
+  bar(y);
+}
+
+__global__ void implicit_as_cast_from_shared_array() {
+  // CHECK: implicit_as_cast_from_shared_array
+  __shared__ int b[1024];
+  // CHECK: addrspacecast
+  bar(b[x]);
+}
+
+__global__ void implicit_as_cast_from_device_scalar() {
+  // CHECK: implicit_as_cast_from_device_scalar
+  __device__ int b;
+  int &y = b;
+  bar(y);
+}
+
+__global__ void implicit_as_cast_from_device_array() {
+  // CHECK: implicit_as_cast_from_device_array
+  __device__ int b[1024];
+  // CHECK: addrspacecast
+  bar(b[x]);
+}
+
Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -2430,7 +2430,7 @@
         // can happen due to trivial type mismatches.
         if (IRArgNo < IRFuncTy->getNumParams() &&
             V->getType() != IRFuncTy->getParamType(IRArgNo))
-          V = Builder.CreateBitCast(V, IRFuncTy->getParamType(IRArgNo));
+          V = EmitImplicitTypeCoercion(V, IRFuncTy->getParamType(IRArgNo));
         Args.push_back(V);
         
         checkArgMatches(V, IRArgNo, IRFuncTy);
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -1432,6 +1432,13 @@
   }
 
   assert(Src.isScalar() && "Can't emit an agg store with this method");
+
+  // Handle CUDA implicit address space conversions.
+  if (getLangOpts().CUDA)
+    if (Src.getScalarVal()->getType()->isPtrOrPtrVectorTy())
+      Src = RValue::get(EmitBitCastOrAddrSpaceCast(Src.getScalarVal(),
+                                                   ConvertType(Dst.getType())));
+
   EmitStoreOfScalar(Src.getScalarVal(), Dst, isInit);
 }
 
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -1499,3 +1499,21 @@
 }
 
 CodeGenFunction::CGCapturedStmtInfo::~CGCapturedStmtInfo() { }
+
+llvm::Value *CodeGenFunction::EmitBitCastOrAddrSpaceCast(llvm::Value *V,
+                                                         llvm::Type *Ty) {
+  if (V->getType()->isPtrOrPtrVectorTy() && Ty->isPtrOrPtrVectorTy() &&
+      V->getType()->getPointerAddressSpace() != Ty->getPointerAddressSpace())
+    return Builder.CreateAddrSpaceCast(V, Ty);
+
+  return Builder.CreateBitCast(V, Ty);
+}
+
+llvm::Value *CodeGenFunction::EmitImplicitTypeCoercion(llvm::Value *V,
+                                                       llvm::Type *Ty) {
+  // Handle implicit pointer address space conversion for CUDA.
+  if (getLangOpts().CUDA)
+    return EmitBitCastOrAddrSpaceCast(V, Ty);
+
+  return Builder.CreateBitCast(V, Ty);
+}
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -2369,6 +2369,9 @@
 
   RValue EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest = 0);
 
+  llvm::Value *EmitImplicitTypeCoercion(llvm::Value *V, llvm::Type *Ty);
+  llvm::Value *EmitBitCastOrAddrSpaceCast(llvm::Value *V, llvm::Type *Ty);
+
   //===--------------------------------------------------------------------===//
   //                         Annotations Emission
   //===--------------------------------------------------------------------===//
Index: test/CodeGenCUDA/address-spaces-implicit-conversion.cu
===================================================================
--- test/CodeGenCUDA/address-spaces-implicit-conversion.cu
+++ test/CodeGenCUDA/address-spaces-implicit-conversion.cu
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -fcuda-is-device -triple nvptx-unknown-unknown | FileCheck %s
+
+#include "../SemaCUDA/cuda.h"
+
+
+__device__ void bar(int &x) {
+  // CHECK: bar
+  x = 0;
+}
+
+int x;
+
+__global__ void implicit_as_cast_from_shared_scalar() {
+  // CHECK: implicit_as_cast_from_shared_scalar
+  __shared__ int b;
+  int &y = b;
+  // CHECK: addrspacecast
+  bar(y);
+}
+
+__global__ void implicit_as_cast_from_shared_array() {
+  // CHECK: implicit_as_cast_from_shared_array
+  __shared__ int b[1024];
+  // CHECK: addrspacecast
+  bar(b[x]);
+}
+
+__global__ void implicit_as_cast_from_device_scalar() {
+  // CHECK: implicit_as_cast_from_device_scalar
+  __device__ int b;
+  int &y = b;
+  bar(y);
+}
+
+__global__ void implicit_as_cast_from_device_array() {
+  // CHECK: implicit_as_cast_from_device_array
+  __device__ int b[1024];
+  // CHECK: addrspacecast
+  bar(b[x]);
+}
+
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to