From: Anastasia Stulova Date: Wed, 17 Feb 2016 11:34:37 +0000 (+0000) Subject: [OpenCL] Added half type literal with suffix h. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2a90a32756ddd2273bc73bf900ef97016f063c1b;p=clang [OpenCL] Added half type literal with suffix h. OpenCL Extension v1.2 s9.5 allows half precision floating point type literals with suffices h or H when cl_khr_fp16 is enabled. Example: half x = 1.0h; Patch by Liu Yaxun (Sam)! Differential Revision: http://reviews.llvm.org/D16865 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@261084 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 4b00445414..a41f1c96dc 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -124,6 +124,8 @@ def warn_float_underflow : Warning< InGroup; def warn_double_const_requires_fp64 : Warning< "double precision constant requires cl_khr_fp64, casting to single precision">; +def err_half_const_requires_fp16 : Error< + "half precision constant requires cl_khr_fp16">; // C99 variable-length arrays def ext_vla : Extension<"variable length arrays are a C99 feature">, diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h index 86935d5936..3a2e8d276e 100644 --- a/include/clang/Lex/LiteralSupport.h +++ b/include/clang/Lex/LiteralSupport.h @@ -61,6 +61,7 @@ public: bool isUnsigned : 1; bool isLong : 1; // This is *not* set for long long. bool isLongLong : 1; + bool isHalf : 1; // 1.0h bool isFloat : 1; // 1.0f bool isImaginary : 1; // 1.0i uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64. diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp index 0c0626c8a8..57494f8743 100644 --- a/lib/Lex/LiteralSupport.cpp +++ b/lib/Lex/LiteralSupport.cpp @@ -522,6 +522,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, isLong = false; isUnsigned = false; isLongLong = false; + isHalf = false; isFloat = false; isImaginary = false; MicrosoftInteger = 0; @@ -555,10 +556,18 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, // we break out of the loop. for (; s != ThisTokEnd; ++s) { switch (*s) { + case 'h': // FP Suffix for "half". + case 'H': + // OpenCL Extension v1.2 s9.5 - h or H suffix for half type. + if (!PP.getLangOpts().Half) break; + if (!isFPConstant) break; // Error for integer constant. + if (isHalf || isFloat || isLong) break; // HH, FH, LH invalid. + isHalf = true; + continue; // Success. case 'f': // FP Suffix for "float" case 'F': if (!isFPConstant) break; // Error for integer constant. - if (isFloat || isLong) break; // FF, LF invalid. + if (isHalf || isFloat || isLong) break; // HF, FF, LF invalid. isFloat = true; continue; // Success. case 'u': @@ -570,7 +579,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, case 'l': case 'L': if (isLong || isLongLong) break; // Cannot be repeated. - if (isFloat) break; // LF invalid. + if (isHalf || isFloat) break; // LH, LF invalid. // Check for long long. The L's need to be adjacent and the same case. if (s[1] == s[0]) { @@ -647,6 +656,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, isUnsigned = false; isLongLong = false; isFloat = false; + isHalf = false; isImaginary = false; MicrosoftInteger = 0; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index bde7cebafe..44a39d7cad 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3295,7 +3295,14 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { if (Literal.isFloatingLiteral()) { QualType Ty; - if (Literal.isFloat) + if (Literal.isHalf){ + if (getOpenCLOptions().cl_khr_fp16) + Ty = Context.HalfTy; + else { + Diag(Tok.getLocation(), diag::err_half_const_requires_fp16); + return ExprError(); + } + } else if (Literal.isFloat) Ty = Context.FloatTy; else if (!Literal.isLong) Ty = Context.DoubleTy; diff --git a/test/Lexer/half-literal.cpp b/test/Lexer/half-literal.cpp new file mode 100644 index 0000000000..32af3faef9 --- /dev/null +++ b/test/Lexer/half-literal.cpp @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s +float a = 1.0h; // expected-error{{invalid suffix 'h' on floating constant}} +float b = 1.0H; // expected-error{{invalid suffix 'H' on floating constant}} diff --git a/test/Lexer/opencl-half-literal.cl b/test/Lexer/opencl-half-literal.cl new file mode 100644 index 0000000000..2415ee4fd8 --- /dev/null +++ b/test/Lexer/opencl-half-literal.cl @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +constant half a = 1.0h; +constant half aa = 1.0H; +constant half b = 1.0hh; // expected-error{{invalid suffix 'hh' on floating constant}} +constant half c = 1.0fh; // expected-error{{invalid suffix 'fh' on floating constant}} +constant half d = 1.0lh; // expected-error{{invalid suffix 'lh' on floating constant}} +constant half e = 1.0hf; // expected-error{{invalid suffix 'hf' on floating constant}} diff --git a/test/SemaOpenCL/half.cl b/test/SemaOpenCL/half.cl index 11abf64633..f8cc017bb8 100644 --- a/test/SemaOpenCL/half.cl +++ b/test/SemaOpenCL/half.cl @@ -1,6 +1,7 @@ // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -Wno-unused-value #pragma OPENCL EXTENSION cl_khr_fp16 : disable +constant float f = 1.0h; // expected-error{{half precision constant requires cl_khr_fp16}} half half_disabled(half *p, // expected-error{{declaring function return value of type 'half' is not allowed}} half h) // expected-error{{declaring function parameter of type 'half' is not allowed}} @@ -12,6 +13,8 @@ half half_disabled(half *p, // expected-error{{declaring function return value o float c = 1.0f; b = (half) c; // expected-error{{casting to type 'half' is not allowed}} + c = (float) 1.0h; // expected-error{{half precision constant requires cl_khr_fp16}} + b = 1.0h; // expected-error{{half precision constant requires cl_khr_fp16}} half *allowed = &p[1]; half *allowed2 = &*p; @@ -22,6 +25,7 @@ half half_disabled(half *p, // expected-error{{declaring function return value o // Exactly the same as above but with the cl_khr_fp16 extension enabled. #pragma OPENCL EXTENSION cl_khr_fp16 : enable +constant half a = 1.0h; half half_enabled(half *p, half h) { half a[2]; @@ -31,6 +35,8 @@ half half_enabled(half *p, half h) float c = 1.0f; b = (half) c; + c = (float) 1.0h; + b = 1.0h; half *allowed = &p[1]; half *allowed2 = &*p;