Prevent atan2 from generating a NaN
TRAC #12184
This is necessary because a NaN generated in flattened conditional code fails to get discarded on certain devices.
Signed-off-by: Shannon Woods
Signed-off-by: Daniel Koch

Author:    Nicolas Capens

git-svn-id: https://angleproject.googlecode.com/svn/trunk@248 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/OutputHLSL.cpp b/src/compiler/OutputHLSL.cpp
index 55f35ae..9f49a76 100644
--- a/src/compiler/OutputHLSL.cpp
+++ b/src/compiler/OutputHLSL.cpp
@@ -50,6 +50,7 @@
     mUsesEqualBVec2 = false;
     mUsesEqualBVec3 = false;
     mUsesEqualBVec4 = false;
+    mUsesAtan2 = false;
 
     mArgumentIndex = 0;
 }
@@ -675,6 +676,15 @@
                "    return v.x == u.x && v.y == u.y && v.z == u.z && v.w == u.w;\n"
                "}\n";
     }
+
+    if (mUsesAtan2)
+    {
+        out << "float atanyx(float y, float x)\n"
+               "{\n"
+               "    if(x == 0 && y == 0) x = 1;\n"   // Avoid producing a NaN
+               "    return atan2(y, x);\n"
+               "}\n";
+    }
 }
 
 void OutputHLSL::footer()
@@ -1450,15 +1460,9 @@
       case EOpMod:              outputTriplet(visit, "mod(", ", ", ")");               break;
       case EOpPow:              outputTriplet(visit, "pow(", ", ", ")");               break;
       case EOpAtan:
-        if (node->getSequence().size() == 1)
-        {
-            outputTriplet(visit, "atan(", ", ", ")");
-        }
-        else if (node->getSequence().size() == 2)
-        {
-            outputTriplet(visit, "atan2(", ", ", ")");
-        }
-        else UNREACHABLE();
+        ASSERT(node->getSequence().size() == 2);   // atan(x) is a unary operator
+        mUsesAtan2 = true;
+        outputTriplet(visit, "atanyx(", ", ", ")");
         break;
       case EOpMin:           outputTriplet(visit, "min(", ", ", ")");           break;
       case EOpMax:           outputTriplet(visit, "max(", ", ", ")");           break;