From c0e5675adf80f12c76eb797de246aa486bc3b0eb Mon Sep 17 00:00:00 2001 From: Neil Hickey Date: Fri, 16 Sep 2016 10:15:06 +0000 Subject: [PATCH] Improve handling of floating point literals in OpenCL to only use double precision if the target supports fp64 https://reviews.llvm.org/D24235 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@281714 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaExpr.cpp | 22 +++++++++++++++++++--- lib/Sema/SemaType.cpp | 3 ++- test/CodeGenOpenCL/fpmath.cl | 13 +++++++++++++ test/SemaOpenCL/extensions.cl | 11 ++++++++++- 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 72a35866ad..53cd35c613 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -828,8 +828,18 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) { // double. const BuiltinType *BTy = Ty->getAs(); 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(); } diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 1619483f08..cd9ebe945f 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -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"; diff --git a/test/CodeGenOpenCL/fpmath.cl b/test/CodeGenOpenCL/fpmath.cl index 780c95f6fb..c23e03b3ff 100644 --- a/test/CodeGenOpenCL/fpmath.cl +++ b/test/CodeGenOpenCL/fpmath.cl @@ -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; } +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" diff --git a/test/SemaOpenCL/extensions.cl b/test/SemaOpenCL/extensions.cl index 31224e0df7..33ed2ce2e7 100644 --- a/test/SemaOpenCL/extensions.cl +++ b/test/SemaOpenCL/extensions.cl @@ -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 -- 2.40.0