Fix HLSL integer pow workaround

The exponent should be rounded prior to casting it to an integer.

Also if the exponent has a significant fractional part the expression
should not be turned into a multiplication. The previous code failed
to check this correctly if the exponent's fractional part was greater
than 0.5.

The test case is expanded to cover the previously failing cases.

BUG=chromium:793115
TEST=angle_end2end_tests

Change-Id: Ic72cd6ddc7f3d2495f7c87a3e3cfac5791445e72
Reviewed-on: https://chromium-review.googlesource.com/817299
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
index d130d63..d0c1b92 100644
--- a/src/tests/gl_tests/GLSLTest.cpp
+++ b/src/tests/gl_tests/GLSLTest.cpp
@@ -1629,22 +1629,28 @@
 // See http://anglebug.com/851
 TEST_P(GLSLTest, PowOfSmallConstant)
 {
-    std::vector<double> bads;
-    for (int eps = -1; eps <= 1; ++eps)
+    // Test with problematic exponents that are close to an integer.
+    std::vector<double> testExponents;
+    std::array<double, 5> epsilonMultipliers = {-100.0, -1.0, 0.0, 1.0, 100.0};
+    for (double epsilonMultiplier : epsilonMultipliers)
     {
         for (int i = -4; i <= 5; ++i)
         {
             if (i >= -1 && i <= 1)
                 continue;
             const double epsilon = 1.0e-8;
-            double bad           = static_cast<double>(i) + static_cast<double>(eps) * epsilon;
-            bads.push_back(bad);
+            double bad           = static_cast<double>(i) + epsilonMultiplier * epsilon;
+            testExponents.push_back(bad);
         }
     }
 
-    for (double bad : bads)
+    // Also test with a few exponents that are not close to an integer.
+    testExponents.push_back(3.6);
+    testExponents.push_back(3.4);
+
+    for (double testExponent : testExponents)
     {
-        const std::string &fragmentShaderSource = GenerateSmallPowShader(1.0e-6, bad);
+        const std::string &fragmentShaderSource = GenerateSmallPowShader(1.0e-6, testExponent);
 
         ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShaderSource);