From 1b42f2a33d2d5a413c3c2d370819d62227b8462a Mon Sep 17 00:00:00 2001
From: John Kessenich <cepheus@frii.com>
Date: Tue, 6 Aug 2013 20:22:51 +0000
Subject: [PATCH] Add parse-time constant folding for isinf() and isnan().

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@22621 e7fa87d3-cd2b-0410-9028-fcbf551c1848
---
 Test/baseResults/constFold.frag.out     | 138 +++++++++++++-----------
 Test/constFold.frag                     |   6 +-
 glslang/MachineIndependent/Constant.cpp |  48 +++++++--
 3 files changed, 119 insertions(+), 73 deletions(-)

diff --git a/Test/baseResults/constFold.frag.out b/Test/baseResults/constFold.frag.out
index f1dd4a757..e8f180ecb 100644
--- a/Test/baseResults/constFold.frag.out
+++ b/Test/baseResults/constFold.frag.out
@@ -1,69 +1,81 @@
 0:? Sequence
-0:24  Function Definition: main( (void)
-0:24    Function Parameters: 
-0:26    Sequence
-0:26      Sequence
-0:26        move second child to first child (4-component vector of float)
-0:26          'dx' (4-component vector of float)
-0:26          dPdx (4-component vector of float)
-0:26            'inv' (smooth in 4-component vector of float)
-0:33      move second child to first child (4-component vector of float)
-0:33        'FragColor' (out 4-component vector of float)
-0:33        2.000000
-0:33        6.000000
-0:33        3.000000
-0:33        171.887339
-0:38      move second child to first child (4-component vector of float)
-0:38        'FragColor' (out 4-component vector of float)
-0:38        3.000000
-0:38        2.000000
-0:38        0.001593
-0:38        -0.999999
-0:39      move second child to first child (2-component vector of float)
-0:39        'out2' (out 2-component vector of float)
-0:39        5.600000
-0:39        5.800000
+0:26  Function Definition: main( (void)
+0:26    Function Parameters: 
+0:28    Sequence
+0:28      Sequence
+0:28        move second child to first child (4-component vector of float)
+0:28          'dx' (4-component vector of float)
+0:28          dPdx (4-component vector of float)
+0:28            'inv' (smooth in 4-component vector of float)
+0:35      move second child to first child (4-component vector of float)
+0:35        'FragColor' (out 4-component vector of float)
+0:35        2.000000
+0:35        6.000000
+0:35        3.000000
+0:35        171.887339
 0:40      move second child to first child (4-component vector of float)
-0:40        'out3' (out 4-component vector of float)
-0:40        20.085537
-0:40        2.302585
-0:40        16.000000
-0:40        8.000000
-0:41      move second child to first child (4-component vector of float)
-0:41        'out4' (out 4-component vector of float)
-0:41        10.000000
-0:41        0.100000
-0:41        4.700000
-0:41        10.900000
-0:42      move second child to first child (4-component vector of int)
-0:42        'out5' (out 4-component vector of int)
-0:42        8 (const int)
-0:42        17 (const int)
-0:42        -1 (const int)
-0:42        1 (const int)
-0:43      move second child to first child (3-component vector of float)
-0:43        'out6' (out 3-component vector of float)
-0:43        -1.000000
-0:43        1.000000
-0:43        0.000000
-0:44      move second child to first child (4-component vector of float)
-0:44        'out7' (out 4-component vector of float)
-0:44        4.000000
-0:44        -4.000000
-0:44        5.000000
-0:44        -5.000000
-0:45      move second child to first child (4-component vector of float)
-0:45        'out8' (out 4-component vector of float)
-0:45        4.000000
-0:45        5.000000
-0:45        4.000000
-0:45        -6.000000
+0:40        'FragColor' (out 4-component vector of float)
+0:40        3.000000
+0:40        2.000000
+0:40        0.001593
+0:40        -0.999999
+0:41      move second child to first child (2-component vector of float)
+0:41        'out2' (out 2-component vector of float)
+0:41        5.600000
+0:41        5.800000
+0:42      move second child to first child (4-component vector of float)
+0:42        'out3' (out 4-component vector of float)
+0:42        20.085537
+0:42        2.302585
+0:42        16.000000
+0:42        8.000000
+0:43      move second child to first child (4-component vector of float)
+0:43        'out4' (out 4-component vector of float)
+0:43        10.000000
+0:43        0.100000
+0:43        4.700000
+0:43        10.900000
+0:44      move second child to first child (4-component vector of int)
+0:44        'out5' (out 4-component vector of int)
+0:44        8 (const int)
+0:44        17 (const int)
+0:44        -1 (const int)
+0:44        1 (const int)
+0:45      move second child to first child (3-component vector of float)
+0:45        'out6' (out 3-component vector of float)
+0:45        -1.000000
+0:45        1.000000
+0:45        0.000000
 0:46      move second child to first child (4-component vector of float)
-0:46        'out9' (out 4-component vector of float)
-0:46        8.000000
+0:46        'out7' (out 4-component vector of float)
+0:46        4.000000
 0:46        -4.000000
-0:46        0.345000
-0:46        0.400000
+0:46        5.000000
+0:46        -5.000000
+0:47      move second child to first child (4-component vector of float)
+0:47        'out8' (out 4-component vector of float)
+0:47        4.000000
+0:47        5.000000
+0:47        4.000000
+0:47        -6.000000
+0:48      move second child to first child (4-component vector of float)
+0:48        'out9' (out 4-component vector of float)
+0:48        8.000000
+0:48        -4.000000
+0:48        0.345000
+0:48        0.400000
+0:49      move second child to first child (4-component vector of float)
+0:49        'out10' (out 4-component vector of float)
+0:49        1.000000
+0:49        1.000000
+0:49        0.000000
+0:49        0.000000
+0:50      move second child to first child (4-component vector of float)
+0:50        'out11' (out 4-component vector of float)
+0:50        0.000000
+0:50        0.000000
+0:50        1.000000
+0:50        0.000000
 0:?   Linker Objects
 0:?     'inv' (smooth in 4-component vector of float)
 0:?     'FragColor' (out 4-component vector of float)
@@ -75,4 +87,6 @@
 0:?     'out7' (out 4-component vector of float)
 0:?     'out8' (out 4-component vector of float)
 0:?     'out9' (out 4-component vector of float)
+0:?     'out10' (out 4-component vector of float)
+0:?     'out11' (out 4-component vector of float)
 
diff --git a/Test/constFold.frag b/Test/constFold.frag
index 302113398..61e5f3b14 100644
--- a/Test/constFold.frag
+++ b/Test/constFold.frag
@@ -20,7 +20,9 @@ out vec3 out6;
 out vec4 out7;
 out vec4 out8;
 out vec4 out9;
-   
+out vec4 out10;
+out vec4 out11;
+
 void main()
 {
     vec4 dx = dFdx(inv);
@@ -44,4 +46,6 @@ void main()
     out7 = vec4(floor(4.2), ceil(-4.1), trunc(5.9), trunc(-5.9)); // 4, -4, 5, -5
     out8 = vec4(round(4.4), round(4.6), roundEven(4.5), roundEven(-5.5)); // 4, 5, 4, -6
     out9 = vec4(roundEven(7.5), roundEven(-4.5), fract(2.345), fract(-2.6)); // 8, -4, .345, 0.4
+    out10 = vec4(isinf(4.0/0.0), isinf(-3.0/0.0), isinf(0.0/0.0), isinf(-93048593405938405938405.0));  // true, true, false, false -> 1.0, 1.0, 0.0, 0.0
+    out11 = vec4(isnan(4.0/0.0), isnan(-3.0/0.0), isnan(0.0/0.0), isnan(-93048593405938405938405.0));  // false, false, true, false -> 0.0, 1.0, 0.0, 0.0
 }
diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp
index fe686254f..742fd9036 100644
--- a/glslang/MachineIndependent/Constant.cpp
+++ b/glslang/MachineIndependent/Constant.cpp
@@ -35,10 +35,32 @@
 //
 
 #include "localintermediate.h"
-#include "math.h"
+#include <cmath>
 #include <cfloat>
 #include <cstdlib>
 
+namespace glslang {
+
+bool isNan(double x)
+{
+    // tough to find a platform independent library function, do it directly
+    int bitPatternL = *(int*)&x;
+    int bitPatternH = *((int*)&x + 1);
+    return (bitPatternH & 0x7ff80000) == 0x7ff80000 && 
+           ((bitPatternH & 0xFFFFF) != 0 || bitPatternL != 0);
+}
+
+bool isInf(double x)
+{
+    // tough to find a platform independent library function, do it directly
+    int bitPatternL = *(int*)&x;
+    int bitPatternH = *((int*)&x + 1);
+    return (bitPatternH & 0x7ff00000) == 0x7ff00000 && 
+           (bitPatternH & 0xFFFFF) == 0 && bitPatternL == 0;
+}
+
+};
+
 namespace {
 
 // Some helper functions
@@ -175,10 +197,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
         for (int i = 0; i < objectSize; i++) {
             switch (getType().getBasicType()) {
             case EbtFloat:
-                if (rightUnionArray[i] == 0.0f) {
-                    newConstArray[i].setDConst(FLT_MAX);  // TODO: double support
-                } else
-                    newConstArray[i].setDConst(unionArray[i].getDConst() / rightUnionArray[i].getDConst());
+                newConstArray[i].setDConst(unionArray[i].getDConst() / rightUnionArray[i].getDConst());
             break;
 
             case EbtInt:
@@ -381,8 +400,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType,
     case EOpAll:
     case EOpLength:
         newConstArray = new constUnion[1];
-        break;        
-    
+        break;
+
     default:
         newConstArray = new constUnion[objectSize];
     }
@@ -539,6 +558,17 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType,
             break;
         }
 
+        case EOpIsNan:
+        {
+            newConstArray[i].setBConst(glslang::isNan(unionArray[i].getDConst()));
+            break;
+        }
+        case EOpIsInf:
+        {
+            newConstArray[i].setBConst(glslang::isInf(unionArray[i].getDConst()));
+            break;
+        }
+
         // TODO: Functionality: constant folding: the rest of the ops have to be fleshed out
 
         case EOpSinh:
@@ -548,13 +578,11 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType,
         case EOpAcosh:
         case EOpAtanh:
 
-        case EOpIsNan:
-        case EOpIsInf:
-
         case EOpFloatBitsToInt:
         case EOpFloatBitsToUint:
         case EOpIntBitsToFloat:
         case EOpUintBitsToFloat:
+
         case EOpPackSnorm2x16:
         case EOpUnpackSnorm2x16:
         case EOpPackUnorm2x16:
-- 
GitLab