Improve handling of floating point literals in OpenCL to only use double precision if the target supports fp64

https://reviews.llvm.org/D24235

llvm-svn: 281714
This commit is contained in:
Neil Hickey 2016-09-16 10:15:06 +00:00
parent d7f2a35cac
commit ddfb093b72
4 changed files with 45 additions and 6 deletions

View File

@ -828,8 +828,18 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) {
// double.
const BuiltinType *BTy = Ty->getAs<BuiltinType>();
if (BTy && (BTy->getKind() == BuiltinType::Half ||
BTy->getKind() == BuiltinType::Float))
E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get();
BTy->getKind() == BuiltinType::Float)) {
if (getLangOpts().OpenCL &&
!((getLangOpts().OpenCLVersion >= 120 &&
Context.getTargetInfo()
.getSupportedOpenCLOpts()
.cl_khr_fp64) ||
getOpenCLOptions().cl_khr_fp64)) {
E = ImpCastExprToType(E, Context.FloatTy, CK_FloatingCast).get();
} else {
E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get();
}
}
// C++ performs lvalue-to-rvalue conversion as a default argument
// promotion, even on class types, but note:
@ -3406,8 +3416,14 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
if (getLangOpts().SinglePrecisionConstants) {
Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get();
} else if (getLangOpts().OpenCL &&
!((getLangOpts().OpenCLVersion >= 120) ||
!((getLangOpts().OpenCLVersion >= 120 &&
Context.getTargetInfo()
.getSupportedOpenCLOpts()
.cl_khr_fp64) ||
getOpenCLOptions().cl_khr_fp64)) {
// Impose single-precision float type when:
// - in CL 1.2 or above and cl_khr_fp64 is not supported, or
// - in CL 1.1 or below and cl_khr_fp64 is not enabled.
Diag(Tok.getLocation(), diag::warn_double_const_requires_fp64);
Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get();
}

View File

@ -1401,7 +1401,8 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
Result = Context.DoubleTy;
if (S.getLangOpts().OpenCL &&
!((S.getLangOpts().OpenCLVersion >= 120) ||
!((S.getLangOpts().OpenCLVersion >= 120
&& S.Context.getTargetInfo().getSupportedOpenCLOpts().cl_khr_fp64) ||
S.getOpenCLOptions().cl_khr_fp64)) {
S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension)
<< Result << "cl_khr_fp64";

View File

@ -1,5 +1,6 @@
// RUN: %clang_cc1 %s -emit-llvm -o - -triple spir-unknown-unknown | FileCheck --check-prefix=CHECK --check-prefix=NODIVOPT %s
// RUN: %clang_cc1 %s -emit-llvm -o - -triple spir-unknown-unknown -cl-fp32-correctly-rounded-divide-sqrt | FileCheck --check-prefix=CHECK --check-prefix=DIVOPT %s
// RUN: %clang_cc1 %s -emit-llvm -o - -DNOFP64 -cl-std=CL1.1 -triple r600-unknown-unknown -target-cpu r600 -pedantic | FileCheck --check-prefix=CHECK-DBL %s
typedef __attribute__(( ext_vector_type(4) )) float float4;
@ -21,14 +22,26 @@ float4 spvectordiv(float4 a, float4 b) {
return a / b;
}
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
void printf(constant char* fmt, ...);
#ifndef NOFP64
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
#endif
void testdbllit(long *val) {
// CHECK-DBL: float 2.000000e+01
// CHECK: double 2.000000e+01
printf("%f", 20.0);
}
#ifndef NOFP64
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
double dpscalardiv(double a, double b) {
// CHECK: @dpscalardiv
// CHECK: #[[ATTR]]
// CHECK-NOT: !fpmath
return a / b;
}
#endif
// CHECK: attributes #[[ATTR]] = {
// NODIVOPT: "correctly-rounded-divide-sqrt-fp-math"="false"

View File

@ -1,13 +1,16 @@
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL1.1
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL1.2 -DFP64
// Test with a target not supporting fp64.
// RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -DNOFP64
#if __OPENCL_C_VERSION__ < 120
void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 extension}}
double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}}
(void) 1.0; // expected-warning {{double precision constant requires cl_khr_fp64}}
}
#endif
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
#ifdef NOFP64
@ -21,8 +24,12 @@ void f2(void) {
#endif
(void) 1.0;
#ifdef FP64
// expected-no-diagnostics
#endif
#ifdef NOFP64
// expected-warning@-2{{double precision constant requires cl_khr_fp64, casting to single precision}}
// expected-warning@-6{{double precision constant requires cl_khr_fp64, casting to single precision}}
#endif
}
@ -31,6 +38,8 @@ void f2(void) {
// expected-warning@-2{{unsupported OpenCL extension 'cl_khr_fp64' - ignoring}}
#endif
#if __OPENCL_C_VERSION__ < 120
void f3(void) {
double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}}
}
#endif