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