Hi rjmccall, rsmith,

This patch introduces a new kind of cast to support explicit address space 
conversions. Starting from llvm r194760 it has been added a new IR instruction 
named 'addrspacecast' that is used to represent conversion between address

This version of the patch now is limited to C pointers, I don't know if this 
would require also the extension other pointer kinds.

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

Files:
  include/clang/AST/OperationKinds.h
  lib/AST/Expr.cpp
  lib/AST/ExprConstant.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGExprAgg.cpp
  lib/CodeGen/CGExprComplex.cpp
  lib/CodeGen/CGExprConstant.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Edit/RewriteObjCFoundationAPI.cpp
  lib/Sema/SemaExpr.cpp
  lib/StaticAnalyzer/Core/ExprEngineC.cpp
  test/CodeGenOpenCL/address-spaces-cast.cl
Index: include/clang/AST/OperationKinds.h
===================================================================
--- include/clang/AST/OperationKinds.h
+++ include/clang/AST/OperationKinds.h
@@ -295,7 +295,11 @@
   CK_BuiltinFnToFnPtr,
 
   // Convert a zero value for OpenCL event_t initialization.
-  CK_ZeroToOCLEvent
+  CK_ZeroToOCLEvent,
+
+  // Conversion of pointer to a pointer in different address space. This cast
+  // should be always explicit except when casting null value.
+  CK_AddressSpaceCast
 };
 
 static const CastKind CK_Invalid = static_cast<CastKind>(-1);
Index: lib/AST/Expr.cpp
===================================================================
--- lib/AST/Expr.cpp
+++ lib/AST/Expr.cpp
@@ -1458,6 +1458,13 @@
     }
     goto CheckNoBasePath;
 
+  case CK_AddressSpaceCast:
+    assert(getType()->isPointerType());
+    assert(getSubExpr()->getType()->isPointerType());
+    assert(getType()->getPointeeType().getAddressSpace() != 
+             getSubExpr()->getType()->getPointeeType().getAddressSpace());
+    goto CheckNoBasePath;
+
   case CK_AnyPointerToBlockPointerCast:
     assert(getType()->isBlockPointerType());
     assert(getSubExpr()->getType()->isAnyPointerType() &&
@@ -1636,6 +1643,8 @@
     return "BuiltinFnToFnPtr";
   case CK_ZeroToOCLEvent:
     return "ZeroToOCLEvent";
+  case CK_AddressSpaceCast:
+    return "AddressSpaceCast";
   }
 
   llvm_unreachable("Unhandled cast kind!");
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -7120,6 +7120,7 @@
   case CK_BuiltinFnToFnPtr:
   case CK_ZeroToOCLEvent:
   case CK_NonAtomicToAtomic:
+  case CK_AddressSpaceCast:
     llvm_unreachable("invalid cast kind for integral value");
 
   case CK_BitCast:
@@ -7592,6 +7593,7 @@
   case CK_BuiltinFnToFnPtr:
   case CK_ZeroToOCLEvent:
   case CK_NonAtomicToAtomic:
+  case CK_AddressSpaceCast:
     llvm_unreachable("invalid cast kind for complex value");
 
   case CK_LValueToRValue:
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -2738,6 +2738,7 @@
   case CK_ARCReclaimReturnedObject:
   case CK_ARCExtendBlockObject:
   case CK_CopyAndAutoreleaseBlockObject:
+  case CK_AddressSpaceCast:
     return EmitUnsupportedLValue(E, "unexpected cast lvalue");
 
   case CK_Dependent:
Index: lib/CodeGen/CGExprAgg.cpp
===================================================================
--- lib/CodeGen/CGExprAgg.cpp
+++ lib/CodeGen/CGExprAgg.cpp
@@ -713,6 +713,7 @@
   case CK_CopyAndAutoreleaseBlockObject:
   case CK_BuiltinFnToFnPtr:
   case CK_ZeroToOCLEvent:
+  case CK_AddressSpaceCast:
     llvm_unreachable("cast kind invalid for aggregate types");
   }
 }
Index: lib/CodeGen/CGExprComplex.cpp
===================================================================
--- lib/CodeGen/CGExprComplex.cpp
+++ lib/CodeGen/CGExprComplex.cpp
@@ -475,6 +475,7 @@
   case CK_CopyAndAutoreleaseBlockObject:
   case CK_BuiltinFnToFnPtr:
   case CK_ZeroToOCLEvent:
+  case CK_AddressSpaceCast:
     llvm_unreachable("invalid cast kind for complex value");
 
   case CK_FloatingRealToComplex:
Index: lib/CodeGen/CGExprConstant.cpp
===================================================================
--- lib/CodeGen/CGExprConstant.cpp
+++ lib/CodeGen/CGExprConstant.cpp
@@ -633,6 +633,9 @@
       return llvm::ConstantStruct::get(STy, Elts);
     }
 
+    case CK_AddressSpaceCast:
+      return llvm::ConstantExpr::getAddrSpaceCast(C, destType);
+
     case CK_LValueToRValue:
     case CK_AtomicToNonAtomic:
     case CK_NonAtomicToAtomic:
Index: lib/CodeGen/CGExprScalar.cpp
===================================================================
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -1301,6 +1301,10 @@
     Value *Src = Visit(const_cast<Expr*>(E));
     return Builder.CreateBitCast(Src, ConvertType(DestTy));
   }
+  case CK_AddressSpaceCast: {
+    Value *Src = Visit(const_cast<Expr*>(E));
+    return Builder.CreatePointerCast(Src, ConvertType(DestTy));
+  }
   case CK_AtomicToNonAtomic:
   case CK_NonAtomicToAtomic:
   case CK_NoOp:
Index: lib/Edit/RewriteObjCFoundationAPI.cpp
===================================================================
--- lib/Edit/RewriteObjCFoundationAPI.cpp
+++ lib/Edit/RewriteObjCFoundationAPI.cpp
@@ -1033,6 +1033,7 @@
     case CK_IntegralComplexToReal:
     case CK_IntegralComplexToBoolean:
     case CK_AtomicToNonAtomic:
+    case CK_AddressSpaceCast:
       needsCast = true;
       break;
 
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -4876,8 +4876,11 @@
   case Type::STK_BlockPointer:
   case Type::STK_ObjCObjectPointer:
     switch (DestTy->getScalarTypeKind()) {
-    case Type::STK_CPointer:
-      return CK_BitCast;
+    case Type::STK_CPointer: {
+      unsigned SrcAS = SrcTy->getPointeeType().getAddressSpace();
+      unsigned DestAS = DestTy->getPointeeType().getAddressSpace();
+      return SrcAS == DestAS ? CK_BitCast : CK_AddressSpaceCast;
+    }
     case Type::STK_BlockPointer:
       return (SrcKind == Type::STK_BlockPointer
                 ? CK_BitCast : CK_AnyPointerToBlockPointerCast);
@@ -7828,10 +7831,14 @@
       diagnoseDistinctPointerComparison(*this, Loc, LHS, RHS, /*isError*/false);
     }
     if (LCanPointeeTy != RCanPointeeTy) {
+      unsigned AddrSpaceL = LCanPointeeTy.getAddressSpace();
+      unsigned AddrSpaceR = RCanPointeeTy.getAddressSpace();
+      CastKind Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceCast
+                                               : CK_BitCast;
       if (LHSIsNull && !RHSIsNull)
-        LHS = ImpCastExprToType(LHS.take(), RHSType, CK_BitCast);
+        LHS = ImpCastExprToType(LHS.take(), RHSType, Kind);
       else
-        RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast);
+        RHS = ImpCastExprToType(RHS.take(), LHSType, Kind);
     }
     return ResultTy;
   }
Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -285,6 +285,7 @@
       case CK_Dependent:
       case CK_ArrayToPointerDecay:
       case CK_BitCast:
+      case CK_AddressSpaceCast:
       case CK_IntegralCast:
       case CK_NullToPointer:
       case CK_IntegralToPointer:
Index: test/CodeGenOpenCL/address-spaces-cast.cl
===================================================================
--- test/CodeGenOpenCL/address-spaces-cast.cl
+++ test/CodeGenOpenCL/address-spaces-cast.cl
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -ffake-address-space-map -emit-llvm -o - | FileCheck %s
+
+#define NULL ((void*)0)
+
+void explicit_cast_between_address_space(int i, __local int *A) {
+// CHECK: explicit_cast_between_address_space
+	__global int *b;
+
+	b = i > 42 ? (__global int *)A : NULL;
+//CHECK: addrspacecast
+
+	if (b)
+	  A[0] = b[5];
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to