Use the [[flatten]] attribute only when a loop is present.

Flattening branch-heavy shaders that contained no loops caused regressions.
As a temporary workaround we only flatten ifs when there exists a loop.

BUG=395048

Change-Id: I95c40f0249643b98c62304a0f2a4563561d1fbbc
Reviewed-on: https://chromium-review.googlesource.com/228722
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
Tested-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 8766bc7..30bbbff 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -135,6 +135,7 @@
     mUniqueIndex = 0;
 
     mContainsLoopDiscontinuity = false;
+    mContainsAnyLoop = false;
     mOutputLod0Function = false;
     mInsideDiscontinuousLoop = false;
     mNestedLoopDepth = 0;
@@ -172,6 +173,7 @@
 void OutputHLSL::output()
 {
     mContainsLoopDiscontinuity = mContext.shaderType == GL_FRAGMENT_SHADER && containsLoopDiscontinuity(mContext.treeRoot);
+    mContainsAnyLoop = containsAnyLoop(mContext.treeRoot);
     const std::vector<TIntermTyped*> &flaggedStructs = FlagStd140ValueStructs(mContext.treeRoot);
     makeFlaggedStructMaps(flaggedStructs);
 
@@ -2301,7 +2303,16 @@
     {
         mUnfoldShortCircuit->traverse(node->getCondition());
 
-        out << "FLATTEN if (";
+        // D3D errors when there is a gradient operation in a loop in an unflattened if
+        // however flattening all the ifs in branch heavy shaders made D3D error too.
+        // As a temporary workaround we flatten the ifs only if there is at least a loop
+        // present somewhere in the shader.
+        if (mContext.shaderType == GL_FRAGMENT_SHADER && mContainsAnyLoop)
+        {
+            out << "FLATTEN ";
+        }
+
+        out << "if (";
 
         node->getCondition()->traverse(this);