[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

llvm-svn: 261084
This commit is contained in:
Anastasia Stulova 2016-02-17 11:34:37 +00:00
parent 219fae9e36
commit 5c1a2c5d3e
7 changed files with 42 additions and 3 deletions

View File

@ -124,6 +124,8 @@ def warn_float_underflow : Warning<
InGroup<LiteralRange>;
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">,

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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}}

View File

@ -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}}

View File

@ -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;