diag::err_typecheck_call_invalid_unary_fp)
<< OrigArg->getType() << OrigArg->getSourceRange();
- // If this is an implicit conversion from float -> double, remove it.
+ // If this is an implicit conversion from float -> float or double, remove it.
if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(OrigArg)) {
Expr *CastArg = Cast->getSubExpr();
if (CastArg->getType()->isSpecificBuiltinType(BuiltinType::Float)) {
- assert(Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) &&
- "promotion from float to double is the only expected cast here");
+ assert((Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) ||
+ Cast->getType()->isSpecificBuiltinType(BuiltinType::Float)) &&
+ "promotion from float to either float or double is the only expected cast here");
Cast->setSubExpr(nullptr);
TheCall->setArg(NumArgs-1, CastArg);
}
// 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 &&
+ !(getOpenCLOptions().cl_khr_fp64)) {
+ if (BTy->getKind() == BuiltinType::Half) {
+ 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:
if (Ty == Context.DoubleTy) {
if (getLangOpts().SinglePrecisionConstants) {
- Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get();
+ const BuiltinType *BTy = Ty->getAs<BuiltinType>();
+ if (BTy->getKind() != BuiltinType::Float) {
+ Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get();
+ }
} else if (getLangOpts().OpenCL &&
- !((getLangOpts().OpenCLVersion >= 120) ||
- getOpenCLOptions().cl_khr_fp64)) {
+ !(getOpenCLOptions().cl_khr_fp64)) {
+ // Impose single-precision float type when cl_khr_fp64 is not enabled.
Diag(Tok.getLocation(), diag::warn_double_const_requires_fp64);
Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get();
}
Result = Context.DoubleTy;
if (S.getLangOpts().OpenCL &&
- !((S.getLangOpts().OpenCLVersion >= 120) ||
- S.getOpenCLOptions().cl_khr_fp64)) {
+ !(S.getOpenCLOptions().cl_khr_fp64)) {
S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension)
<< Result << "cl_khr_fp64";
declarator.setInvalidType(true);
// 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.2 -triple r600-unknown-unknown -target-cpu r600 -pedantic | FileCheck --check-prefix=CHECK-FLT %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -DFP64 -cl-std=CL1.2 -pedantic | FileCheck --check-prefix=CHECK-DBL %s
typedef __attribute__(( ext_vector_type(4) )) float float4;
return a / b;
}
-#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+#if __OPENCL_C_VERSION__ >=120
+void printf(constant char* fmt, ...);
+
+void testdbllit(long *val) {
+ // CHECK-FLT: float 2.000000e+01
+ // CHECK-DBL: double 2.000000e+01
+ printf("%f", 20.0);
+}
+#endif
+
+#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"
// 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 -DNOFP16
+#ifdef FP64
+// expected-no-diagnostics
+#endif
+
+#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
#endif
(void) 1.0;
+
#ifdef NOFP64
-// expected-warning@-2{{double precision constant requires cl_khr_fp64, casting to single precision}}
+// expected-warning@-3{{double precision constant requires cl_khr_fp64, casting to single precision}}
#endif
}
// 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