diff options
author | Joey Gouly <joey.gouly@arm.com> | 2013-01-23 11:56:20 +0000 |
---|---|---|
committer | Joey Gouly <joey.gouly@arm.com> | 2013-01-23 11:56:20 +0000 |
commit | 19dbb20ac4371fae3190379a7e7bd467af3c00aa (patch) | |
tree | 4ad0ff118896e57acd79d0f76e8a57311af4bd19 /lib/Sema | |
parent | 218b6dfaee321cec558e15d47b68155dd9f35684 (diff) |
Add a new LangOpt NativeHalfType. This option allows for native half/fp16
operations (as opposed to storage only half/fp16).
Also add some semantic checks for OpenCL half types.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173254 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaCast.cpp | 15 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 11 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 21 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 29 |
5 files changed, 66 insertions, 13 deletions
diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp index 676db464b6..d1e95d7df9 100644 --- a/lib/Sema/SemaCast.cpp +++ b/lib/Sema/SemaCast.cpp @@ -2104,6 +2104,21 @@ void CastOperation::CheckCStyleCast() { } } + if (Self.getLangOpts().OpenCL && !Self.getOpenCLOptions().cl_khr_fp16) { + if (DestType->isHalfType()) { + Self.Diag(SrcExpr.get()->getLocStart(), diag::err_opencl_cast_to_half) + << DestType << SrcExpr.get()->getSourceRange(); + SrcExpr = ExprError(); + return; + } + if (SrcExpr.get()->getType()->isHalfType()) { + Self.Diag(SrcExpr.get()->getLocStart(), diag::err_opencl_cast_from_half) + << SrcType << SrcExpr.get()->getSourceRange(); + SrcExpr = ExprError(); + return; + } + } + // ARC imposes extra restrictions on casts. if (Self.getLangOpts().ObjCAutoRefCount) { checkObjCARCConversion(Sema::CCK_CStyleCast); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index f73ea9875a..2a1894674a 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -4359,6 +4359,17 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, assert(SCSpec != DeclSpec::SCS_typedef && "Parser allowed 'typedef' as storage class VarDecl."); VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(SCSpec); + + if (getLangOpts().OpenCL && !getOpenCLOptions().cl_khr_fp16) + { + // OpenCL v1.2 s6.1.1.1: reject declaring variables of the half and + // half array type (unless the cl_khr_fp16 extension is enabled). + if (Context.getBaseElementType(R)->isHalfType()) { + Diag(D.getIdentifierLoc(), diag::err_opencl_half_declaration) << R; + D.setInvalidType(); + } + } + if (SCSpec == DeclSpec::SCS_mutable) { // mutable can only appear on non-static class members, so it's always // an error here diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 3cca25a814..2e1188164d 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -545,9 +545,8 @@ ExprResult Sema::UsualUnaryConversions(Expr *E) { QualType Ty = E->getType(); assert(!Ty.isNull() && "UsualUnaryConversions - missing type"); - // Half FP is a bit different: it's a storage-only type, meaning that any - // "use" of it should be promoted to float. - if (Ty->isHalfType()) + // Half FP have to be promoted to float unless it is natively supported + if (Ty->isHalfType() && !getLangOpts().NativeHalfType) return ImpCastExprToType(Res.take(), Context.FloatTy, CK_FloatingCast); // Try to perform integral promotions if the object has a theoretically @@ -3470,6 +3469,13 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, diag::err_subscript_incomplete_type, BaseExpr)) return ExprError(); + if (ResultType->isHalfType() && getLangOpts().OpenCL && + !getOpenCLOptions().cl_khr_fp16) { + Diag(BaseExpr->getLocStart(), diag::err_opencl_half_subscript) << ResultType + << BaseExpr->getType() << BaseExpr->getSourceRange(); + return ExprError(); + } + assert(VK == VK_RValue || LangOpts.CPlusPlus || !ResultType.isCForbiddenLValueType()); @@ -8210,6 +8216,13 @@ static QualType CheckIndirectionOperand(Sema &S, Expr *Op, ExprValueKind &VK, return QualType(); } + if (Result->isHalfType() && S.getLangOpts().OpenCL && + !S.getOpenCLOptions().cl_khr_fp16) { + S.Diag(OpLoc, diag::err_opencl_half_dereferencing) + << OpTy << Op->getSourceRange(); + return QualType(); + } + // Dereferences are usually l-values... VK = VK_LValue; @@ -8831,7 +8844,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, resultType = Input.get()->getType(); // Though we still have to promote half FP to float... - if (resultType->isHalfType()) { + if (resultType->isHalfType() && !Context.getLangOpts().NativeHalfType) { Input = ImpCastExprToType(Input.take(), Context.FloatTy, CK_FloatingCast).take(); resultType = Context.FloatTy; } diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index d3d027b8a5..b91b027ba0 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -1840,7 +1840,8 @@ bool Sema::IsFloatingPointPromotion(QualType FromType, QualType ToType) { return true; // Half can be promoted to float. - if (FromBuiltin->getKind() == BuiltinType::Half && + if (!getLangOpts().NativeHalfType && + FromBuiltin->getKind() == BuiltinType::Half && ToBuiltin->getKind() == BuiltinType::Float) return true; } diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index a3b0c45b9d..dbee50a4c9 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -2441,10 +2441,16 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, // Do not allow returning half FP value. // FIXME: This really should be in BuildFunctionType. if (T->isHalfType()) { - S.Diag(D.getIdentifierLoc(), - diag::err_parameters_retval_cannot_have_fp16_type) << 1 - << FixItHint::CreateInsertion(D.getIdentifierLoc(), "*"); - D.setInvalidType(true); + if (S.getLangOpts().OpenCL) { + if (!S.getOpenCLOptions().cl_khr_fp16) { + S.Diag(D.getIdentifierLoc(), diag::err_opencl_half_return) << T; + D.setInvalidType(true); + } + } else { + S.Diag(D.getIdentifierLoc(), + diag::err_parameters_retval_cannot_have_fp16_type) << 1; + D.setInvalidType(true); + } } // cv-qualifiers on return types are pointless except when the type is a @@ -2617,10 +2623,17 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, } else if (ArgTy->isHalfType()) { // Disallow half FP arguments. // FIXME: This really should be in BuildFunctionType. - S.Diag(Param->getLocation(), - diag::err_parameters_retval_cannot_have_fp16_type) << 0 - << FixItHint::CreateInsertion(Param->getLocation(), "*"); - D.setInvalidType(); + if (S.getLangOpts().OpenCL) { + if (!S.getOpenCLOptions().cl_khr_fp16) { + S.Diag(Param->getLocation(), + diag::err_opencl_half_argument) << ArgTy; + D.setInvalidType(); + } + } else { + S.Diag(Param->getLocation(), + diag::err_parameters_retval_cannot_have_fp16_type) << 0; + D.setInvalidType(); + } } else if (!FTI.hasPrototype) { if (ArgTy->isPromotableIntegerType()) { ArgTy = Context.getPromotedIntegerType(ArgTy); |