Use intermOut.cpp's IsNan and IsInfinity for parse-time constant folding (updated)
authorMarius Hillenbrand <mhillen@linux.ibm.com>
Tue, 9 Nov 2021 15:31:22 +0000 (16:31 +0100)
committerMarius Hillenbrand <mhillen@linux.ibm.com>
Thu, 11 Nov 2021 15:49:40 +0000 (16:49 +0100)
There were two implementations of isInf() and isNan(), in Constant.cpp
and in intermOut.cpp. The former only works on little-endian systems,
the latter is a wrapper for library functions and works regardless of
endianness. Move the second version into Common.h and adopt it in both
places. Thereby avoid the duplication and fix for big-endian systems.

A previous commit with the same intent and purpose had missed a required
header for builds on Windows.

On s390x, this fixes the test case
Glsl/CompileToAstTest.FromFile/constFold_frag.

Fixes #2802

glslang/Include/Common.h
glslang/MachineIndependent/Constant.cpp
glslang/MachineIndependent/intermOut.cpp

index e7b5e07..9042a1a 100644 (file)
 
 #include <algorithm>
 #include <cassert>
+#ifdef _MSC_VER
+#include <cfloat>
+#else
+#include <cmath>
+#endif
 #include <cstdio>
 #include <cstdlib>
 #include <list>
@@ -302,6 +307,34 @@ template <class T> int IntLog2(T n)
     return result;
 }
 
+inline bool IsInfinity(double x) {
+#ifdef _MSC_VER
+    switch (_fpclass(x)) {
+    case _FPCLASS_NINF:
+    case _FPCLASS_PINF:
+        return true;
+    default:
+        return false;
+    }
+#else
+    return std::isinf(x);
+#endif
+}
+
+inline bool IsNan(double x) {
+#ifdef _MSC_VER
+    switch (_fpclass(x)) {
+    case _FPCLASS_SNAN:
+    case _FPCLASS_QNAN:
+        return true;
+    default:
+        return false;
+    }
+#else
+  return std::isnan(x);
+#endif
+}
+
 } // end namespace glslang
 
 #endif // _COMMON_INCLUDED_
index 7f5d4c4..5fc61db 100644 (file)
@@ -46,35 +46,6 @@ namespace {
 
 using namespace glslang;
 
-typedef union {
-    double d;
-    int i[2];
-} DoubleIntUnion;
-
-// Some helper functions
-
-bool isNan(double x)
-{
-    DoubleIntUnion u;
-    // tough to find a platform independent library function, do it directly
-    u.d = x;
-    int bitPatternL = u.i[0];
-    int bitPatternH = u.i[1];
-    return (bitPatternH & 0x7ff80000) == 0x7ff80000 &&
-           ((bitPatternH & 0xFFFFF) != 0 || bitPatternL != 0);
-}
-
-bool isInf(double x)
-{
-    DoubleIntUnion u;
-    // tough to find a platform independent library function, do it directly
-    u.d = x;
-    int bitPatternL = u.i[0];
-    int bitPatternH = u.i[1];
-    return (bitPatternH & 0x7ff00000) == 0x7ff00000 &&
-           (bitPatternH & 0xFFFFF) == 0 && bitPatternL == 0;
-}
-
 const double pi = 3.1415926535897932384626433832795;
 
 } // end anonymous namespace
@@ -663,12 +634,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
 
         case EOpIsNan:
         {
-            newConstArray[i].setBConst(isNan(unionArray[i].getDConst()));
+            newConstArray[i].setBConst(IsNan(unionArray[i].getDConst()));
             break;
         }
         case EOpIsInf:
         {
-            newConstArray[i].setBConst(isInf(unionArray[i].getDConst()));
+            newConstArray[i].setBConst(IsInfinity(unionArray[i].getDConst()));
             break;
         }
 
index a0fade1..d8a3aab 100644 (file)
 #endif
 #include <cstdint>
 
-namespace {
-
-bool IsInfinity(double x) {
-#ifdef _MSC_VER
-    switch (_fpclass(x)) {
-    case _FPCLASS_NINF:
-    case _FPCLASS_PINF:
-        return true;
-    default:
-        return false;
-    }
-#else
-    return std::isinf(x);
-#endif
-}
-
-bool IsNan(double x) {
-#ifdef _MSC_VER
-    switch (_fpclass(x)) {
-    case _FPCLASS_SNAN:
-    case _FPCLASS_QNAN:
-        return true;
-    default:
-        return false;
-    }
-#else
-  return std::isnan(x);
-#endif
-}
-
-}
 
 namespace glslang {