From 2a8d5cd18041944b99cea3eafe3da0f65c8965b3 Mon Sep 17 00:00:00 2001
From: Neil Hickey <neil.hickey@arm.com>
Date: Wed, 14 Dec 2016 13:18:48 +0000
Subject: [PATCH] Fixing cast condition for removing casts from builtin
 FPClassification.

The function SemaBuiltinFPClassification removed superfluous float to double
casts, this was changed to also remove float to float casts but this isn't
valid in all cases, for example when doing an rvaluetolvalue cast. Added a
check to only remove if this was a conventional floating cast.

Added additional tests into SemaOpenCL/extensions to cover these cases



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@289650 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaChecking.cpp     | 17 ++++++++++-------
 test/SemaOpenCL/extensions.cl |  8 ++++++++
 2 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index b51cf56f01e..450e2789c79 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -3750,13 +3750,16 @@ bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) {
 
   // 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) ||
-                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);
+    // Only remove standard FloatCasts, leaving other casts inplace
+    if (Cast->getCastKind() == CK_FloatingCast) {
+      Expr *CastArg = Cast->getSubExpr();
+      if (CastArg->getType()->isSpecificBuiltinType(BuiltinType::Float)) {
+          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);
+      }
     }
   }
   
diff --git a/test/SemaOpenCL/extensions.cl b/test/SemaOpenCL/extensions.cl
index b03428ad33b..688185ec207 100644
--- a/test/SemaOpenCL/extensions.cl
+++ b/test/SemaOpenCL/extensions.cl
@@ -35,6 +35,14 @@ void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 exte
 }
 #endif
 
+int isnan(float x) {
+    return __builtin_isnan(x);
+}
+
+int isfinite(float x) {
+    return __builtin_isfinite(x);
+}
+
 #pragma OPENCL EXTENSION cl_khr_fp64 : enable
 #ifdef NOFP64
 // expected-warning@-2{{unsupported OpenCL extension 'cl_khr_fp64' - ignoring}}
-- 
GitLab