Revert "Make sure type gets set consistently in folded binary operations"

This is blocking the revert of the geometric constant folding 
patch, which is breaking gpu_unittests and blocking the roll.

BUG=angleproject:817

This reverts commit b07aba0798d3bba3118dac78933e73b3f08a601b.

Change-Id: Ia00fc45b1ddd9d3c079742dea0627aa12304f93b
Reviewed-on: https://chromium-review.googlesource.com/275321
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index 680ca78..5aed4f8 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -747,376 +747,14 @@
     return true;
 }
 
-TIntermTyped *TIntermBinary::fold(TInfoSink &infoSink)
-{
-    TIntermConstantUnion *leftConstant = mLeft->getAsConstantUnion();
-    TIntermConstantUnion *rightConstant = mRight->getAsConstantUnion();
-    if (leftConstant == nullptr || rightConstant == nullptr)
-    {
-        return nullptr;
-    }
-    TConstantUnion *constArray = leftConstant->foldBinary(mOp, rightConstant, infoSink);
-    if (constArray == nullptr)
-    {
-        return nullptr;
-    }
-    TIntermTyped *folded = new TIntermConstantUnion(constArray, getType());
-    folded->getTypePointer()->setQualifier(EvqConst);
-    folded->setLine(getLine());
-    return folded;
-}
-
 //
 // The fold functions see if an operation on a constant can be done in place,
 // without generating run-time code.
 //
-// Returns the constant value to keep using or nullptr.
+// Returns the node to keep using, which may or may not be the node passed in.
 //
-TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink)
-{
-    TConstantUnion *leftArray = getUnionArrayPointer();
-    TConstantUnion *rightArray = rightNode->getUnionArrayPointer();
-
-    if (!leftArray)
-        return nullptr;
-    if (!rightArray)
-        return nullptr;
-
-    size_t objectSize = getType().getObjectSize();
-
-    // for a case like float f = vec4(2, 3, 4, 5) + 1.2;
-    if (rightNode->getType().getObjectSize() == 1 && objectSize > 1)
-    {
-        rightArray = Vectorize(*rightNode->getUnionArrayPointer(), objectSize);
-    }
-    else if (rightNode->getType().getObjectSize() > 1 && objectSize == 1)
-    {
-        // for a case like float f = 1.2 + vec4(2, 3, 4, 5);
-        leftArray = Vectorize(*getUnionArrayPointer(), rightNode->getType().getObjectSize());
-        objectSize = rightNode->getType().getObjectSize();
-    }
-
-    TConstantUnion *resultArray = nullptr;
-
-    switch(op)
-    {
-      case EOpAdd:
-        resultArray = new TConstantUnion[objectSize];
-        for (size_t i = 0; i < objectSize; i++)
-            resultArray[i] = leftArray[i] + rightArray[i];
-        break;
-      case EOpSub:
-        resultArray = new TConstantUnion[objectSize];
-        for (size_t i = 0; i < objectSize; i++)
-            resultArray[i] = leftArray[i] - rightArray[i];
-        break;
-
-      case EOpMul:
-      case EOpVectorTimesScalar:
-      case EOpMatrixTimesScalar:
-        resultArray = new TConstantUnion[objectSize];
-        for (size_t i = 0; i < objectSize; i++)
-            resultArray[i] = leftArray[i] * rightArray[i];
-        break;
-
-      case EOpMatrixTimesMatrix:
-        {
-            if (getType().getBasicType() != EbtFloat ||
-                rightNode->getBasicType() != EbtFloat)
-            {
-                infoSink.info.message(
-                    EPrefixInternalError, getLine(),
-                    "Constant Folding cannot be done for matrix multiply");
-                return nullptr;
-            }
-
-            const int leftCols = getCols();
-            const int leftRows = getRows();
-            const int rightCols = rightNode->getType().getCols();
-            const int rightRows = rightNode->getType().getRows();
-            const int resultCols = rightCols;
-            const int resultRows = leftRows;
-
-            resultArray = new TConstantUnion[resultCols * resultRows];
-            for (int row = 0; row < resultRows; row++)
-            {
-                for (int column = 0; column < resultCols; column++)
-                {
-                    resultArray[resultRows * column + row].setFConst(0.0f);
-                    for (int i = 0; i < leftCols; i++)
-                    {
-                        resultArray[resultRows * column + row].setFConst(
-                            resultArray[resultRows * column + row].getFConst() +
-                            leftArray[i * leftRows + row].getFConst() *
-                            rightArray[column * rightRows + i].getFConst());
-                    }
-                }
-            }
-        }
-        break;
-
-      case EOpDiv:
-      case EOpIMod:
-        {
-            resultArray = new TConstantUnion[objectSize];
-            for (size_t i = 0; i < objectSize; i++)
-            {
-                switch (getType().getBasicType())
-                {
-                  case EbtFloat:
-                    if (rightArray[i] == 0.0f)
-                    {
-                        infoSink.info.message(EPrefixWarning, getLine(),
-                                              "Divide by zero error during constant folding");
-                        resultArray[i].setFConst(leftArray[i].getFConst() < 0 ? -FLT_MAX : FLT_MAX);
-                    }
-                    else
-                    {
-                        ASSERT(op == EOpDiv);
-                        resultArray[i].setFConst(leftArray[i].getFConst() / rightArray[i].getFConst());
-                    }
-                    break;
-
-                  case EbtInt:
-                    if (rightArray[i] == 0)
-                    {
-                        infoSink.info.message(EPrefixWarning, getLine(),
-                                              "Divide by zero error during constant folding");
-                        resultArray[i].setIConst(INT_MAX);
-                    }
-                    else
-                    {
-                        if (op == EOpDiv)
-                        {
-                            resultArray[i].setIConst(leftArray[i].getIConst() / rightArray[i].getIConst());
-                        }
-                        else
-                        {
-                            ASSERT(op == EOpIMod);
-                            resultArray[i].setIConst(leftArray[i].getIConst() % rightArray[i].getIConst());
-                        }
-                    }
-                    break;
-
-                  case EbtUInt:
-                    if (rightArray[i] == 0)
-                    {
-                        infoSink.info.message(EPrefixWarning, getLine(),
-                                              "Divide by zero error during constant folding");
-                        resultArray[i].setUConst(UINT_MAX);
-                    }
-                    else
-                    {
-                        if (op == EOpDiv)
-                        {
-                            resultArray[i].setUConst(leftArray[i].getUConst() / rightArray[i].getUConst());
-                        }
-                        else
-                        {
-                            ASSERT(op == EOpIMod);
-                            resultArray[i].setUConst(leftArray[i].getUConst() % rightArray[i].getUConst());
-                        }
-                    }
-                    break;
-
-                  default:
-                    infoSink.info.message(EPrefixInternalError, getLine(),
-                                          "Constant folding cannot be done for \"/\"");
-                    return nullptr;
-                }
-            }
-        }
-        break;
-
-      case EOpMatrixTimesVector:
-        {
-            if (rightNode->getBasicType() != EbtFloat)
-            {
-                infoSink.info.message(EPrefixInternalError, getLine(),
-                                      "Constant Folding cannot be done for matrix times vector");
-                return nullptr;
-            }
-
-            const int matrixCols = getCols();
-            const int matrixRows = getRows();
-
-            resultArray = new TConstantUnion[matrixRows];
-
-            for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++)
-            {
-                resultArray[matrixRow].setFConst(0.0f);
-                for (int col = 0; col < matrixCols; col++)
-                {
-                    resultArray[matrixRow].setFConst(resultArray[matrixRow].getFConst() +
-                                                     leftArray[col * matrixRows + matrixRow].getFConst() *
-                                                     rightArray[col].getFConst());
-                }
-            }
-        }
-        break;
-
-      case EOpVectorTimesMatrix:
-        {
-            if (getType().getBasicType() != EbtFloat)
-            {
-                infoSink.info.message(EPrefixInternalError, getLine(),
-                                      "Constant Folding cannot be done for vector times matrix");
-                return nullptr;
-            }
-
-            const int matrixCols = rightNode->getType().getCols();
-            const int matrixRows = rightNode->getType().getRows();
-
-            resultArray = new TConstantUnion[matrixCols];
-
-            for (int matrixCol = 0; matrixCol < matrixCols; matrixCol++)
-            {
-                resultArray[matrixCol].setFConst(0.0f);
-                for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++)
-                {
-                    resultArray[matrixCol].setFConst(resultArray[matrixCol].getFConst() +
-                                                     leftArray[matrixRow].getFConst() *
-                                                     rightArray[matrixCol * matrixRows + matrixRow].getFConst());
-                }
-            }
-        }
-        break;
-
-      case EOpLogicalAnd:
-        {
-            resultArray = new TConstantUnion[objectSize];
-            for (size_t i = 0; i < objectSize; i++)
-            {
-                resultArray[i] = leftArray[i] && rightArray[i];
-            }
-        }
-        break;
-
-      case EOpLogicalOr:
-        {
-            resultArray = new TConstantUnion[objectSize];
-            for (size_t i = 0; i < objectSize; i++)
-            {
-                resultArray[i] = leftArray[i] || rightArray[i];
-            }
-        }
-        break;
-
-      case EOpLogicalXor:
-        {
-            resultArray = new TConstantUnion[objectSize];
-            for (size_t i = 0; i < objectSize; i++)
-            {
-                switch (getType().getBasicType())
-                {
-                  case EbtBool:
-                    resultArray[i].setBConst(leftArray[i] != rightArray[i]);
-                    break;
-                  default:
-                    UNREACHABLE();
-                    break;
-                }
-            }
-        }
-        break;
-
-      case EOpBitwiseAnd:
-        resultArray = new TConstantUnion[objectSize];
-        for (size_t i = 0; i < objectSize; i++)
-            resultArray[i] = leftArray[i] & rightArray[i];
-        break;
-      case EOpBitwiseXor:
-        resultArray = new TConstantUnion[objectSize];
-        for (size_t i = 0; i < objectSize; i++)
-            resultArray[i] = leftArray[i] ^ rightArray[i];
-        break;
-      case EOpBitwiseOr:
-        resultArray = new TConstantUnion[objectSize];
-        for (size_t i = 0; i < objectSize; i++)
-            resultArray[i] = leftArray[i] | rightArray[i];
-        break;
-      case EOpBitShiftLeft:
-        resultArray = new TConstantUnion[objectSize];
-        for (size_t i = 0; i < objectSize; i++)
-            resultArray[i] = leftArray[i] << rightArray[i];
-        break;
-      case EOpBitShiftRight:
-        resultArray = new TConstantUnion[objectSize];
-        for (size_t i = 0; i < objectSize; i++)
-            resultArray[i] = leftArray[i] >> rightArray[i];
-        break;
-
-      case EOpLessThan:
-        ASSERT(objectSize == 1);
-        resultArray = new TConstantUnion[1];
-        resultArray->setBConst(*leftArray < *rightArray);
-        break;
-
-      case EOpGreaterThan:
-        ASSERT(objectSize == 1);
-        resultArray = new TConstantUnion[1];
-        resultArray->setBConst(*leftArray > *rightArray);
-        break;
-
-      case EOpLessThanEqual:
-        ASSERT(objectSize == 1);
-        resultArray = new TConstantUnion[1];
-        resultArray->setBConst(!(*leftArray > *rightArray));
-        break;
-
-      case EOpGreaterThanEqual:
-        ASSERT(objectSize == 1);
-        resultArray = new TConstantUnion[1];
-        resultArray->setBConst(!(*leftArray < *rightArray));
-        break;
-
-      case EOpEqual:
-      case EOpNotEqual:
-        {
-            resultArray = new TConstantUnion[1];
-            bool equal = true;
-            if (getType().getBasicType() == EbtStruct)
-            {
-                equal = CompareStructure(getType(), rightArray, leftArray);
-            }
-            else
-            {
-                for (size_t i = 0; i < objectSize; i++)
-                {
-                    if (leftArray[i] != rightArray[i])
-                    {
-                        equal = false;
-                        break;  // break out of for loop
-                    }
-                }
-            }
-            if (op == EOpEqual)
-            {
-                resultArray->setBConst(equal);
-            }
-            else
-            {
-                resultArray->setBConst(!equal);
-            }
-        }
-        break;
-
-      default:
-        infoSink.info.message(
-            EPrefixInternalError, getLine(),
-            "Invalid operator for constant folding");
-        return nullptr;
-    }
-    return resultArray;
-}
-
-//
-// The fold functions see if an operation on a constant can be done in place,
-// without generating run-time code.
-//
-// Returns the node to keep using or nullptr.
-//
-TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
+TIntermTyped *TIntermConstantUnion::fold(
+    TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink)
 {
     TConstantUnion *unionArray = getUnionArrayPointer();
 
@@ -1125,7 +763,442 @@
 
     size_t objectSize = getType().getObjectSize();
 
-    if (op == EOpAny || op == EOpAll || op == EOpLength)
+    if (rightNode)
+    {
+        // binary operations
+        TConstantUnion *rightUnionArray = rightNode->getUnionArrayPointer();
+        TType returnType = getType();
+
+        if (!rightUnionArray)
+            return nullptr;
+
+        // for a case like float f = vec4(2, 3, 4, 5) + 1.2;
+        if (rightNode->getType().getObjectSize() == 1 && objectSize > 1)
+        {
+            rightUnionArray = Vectorize(*rightNode->getUnionArrayPointer(), objectSize);
+            returnType = getType();
+        }
+        else if (rightNode->getType().getObjectSize() > 1 && objectSize == 1)
+        {
+            // for a case like float f = 1.2 + vec4(2, 3, 4, 5);
+            unionArray = Vectorize(*getUnionArrayPointer(), rightNode->getType().getObjectSize());
+            returnType = rightNode->getType();
+            objectSize = rightNode->getType().getObjectSize();
+        }
+
+        TConstantUnion *tempConstArray = nullptr;
+        TIntermConstantUnion *tempNode;
+
+        bool boolNodeFlag = false;
+        switch(op)
+        {
+          case EOpAdd:
+            tempConstArray = new TConstantUnion[objectSize];
+            for (size_t i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] + rightUnionArray[i];
+            break;
+          case EOpSub:
+            tempConstArray = new TConstantUnion[objectSize];
+            for (size_t i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] - rightUnionArray[i];
+            break;
+
+          case EOpMul:
+          case EOpVectorTimesScalar:
+          case EOpMatrixTimesScalar:
+            tempConstArray = new TConstantUnion[objectSize];
+            for (size_t i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] * rightUnionArray[i];
+            break;
+
+          case EOpMatrixTimesMatrix:
+            {
+                if (getType().getBasicType() != EbtFloat ||
+                    rightNode->getBasicType() != EbtFloat)
+                {
+                    infoSink.info.message(
+                        EPrefixInternalError, getLine(),
+                        "Constant Folding cannot be done for matrix multiply");
+                    return nullptr;
+                }
+
+                const int leftCols = getCols();
+                const int leftRows = getRows();
+                const int rightCols = rightNode->getType().getCols();
+                const int rightRows = rightNode->getType().getRows();
+                const int resultCols = rightCols;
+                const int resultRows = leftRows;
+
+                tempConstArray = new TConstantUnion[resultCols * resultRows];
+                for (int row = 0; row < resultRows; row++)
+                {
+                    for (int column = 0; column < resultCols; column++)
+                    {
+                        tempConstArray[resultRows * column + row].setFConst(0.0f);
+                        for (int i = 0; i < leftCols; i++)
+                        {
+                            tempConstArray[resultRows * column + row].setFConst(
+                                tempConstArray[resultRows * column + row].getFConst() +
+                                unionArray[i * leftRows + row].getFConst() *
+                                rightUnionArray[column * rightRows + i].getFConst());
+                        }
+                    }
+                }
+
+                // update return type for matrix product
+                returnType.setPrimarySize(static_cast<unsigned char>(resultCols));
+                returnType.setSecondarySize(static_cast<unsigned char>(resultRows));
+            }
+            break;
+
+          case EOpDiv:
+          case EOpIMod:
+            {
+                tempConstArray = new TConstantUnion[objectSize];
+                for (size_t i = 0; i < objectSize; i++)
+                {
+                    switch (getType().getBasicType())
+                    {
+                      case EbtFloat:
+                        if (rightUnionArray[i] == 0.0f)
+                        {
+                            infoSink.info.message(
+                                EPrefixWarning, getLine(),
+                                "Divide by zero error during constant folding");
+                            tempConstArray[i].setFConst(
+                                unionArray[i].getFConst() < 0 ? -FLT_MAX : FLT_MAX);
+                        }
+                        else
+                        {
+                            ASSERT(op == EOpDiv);
+                            tempConstArray[i].setFConst(
+                                unionArray[i].getFConst() /
+                                rightUnionArray[i].getFConst());
+                        }
+                        break;
+
+                      case EbtInt:
+                        if (rightUnionArray[i] == 0)
+                        {
+                            infoSink.info.message(
+                                EPrefixWarning, getLine(),
+                                "Divide by zero error during constant folding");
+                            tempConstArray[i].setIConst(INT_MAX);
+                        }
+                        else
+                        {
+                            if (op == EOpDiv)
+                            {
+                                tempConstArray[i].setIConst(
+                                    unionArray[i].getIConst() /
+                                    rightUnionArray[i].getIConst());
+                            }
+                            else
+                            {
+                                ASSERT(op == EOpIMod);
+                                tempConstArray[i].setIConst(
+                                    unionArray[i].getIConst() %
+                                    rightUnionArray[i].getIConst());
+                            }
+                        }
+                        break;
+
+                      case EbtUInt:
+                        if (rightUnionArray[i] == 0)
+                        {
+                            infoSink.info.message(
+                                EPrefixWarning, getLine(),
+                                "Divide by zero error during constant folding");
+                            tempConstArray[i].setUConst(UINT_MAX);
+                        }
+                        else
+                        {
+                            if (op == EOpDiv)
+                            {
+                                tempConstArray[i].setUConst(
+                                    unionArray[i].getUConst() /
+                                    rightUnionArray[i].getUConst());
+                            }
+                            else
+                            {
+                                ASSERT(op == EOpIMod);
+                                tempConstArray[i].setUConst(
+                                    unionArray[i].getUConst() %
+                                    rightUnionArray[i].getUConst());
+                            }
+                        }
+                        break;
+
+                      default:
+                        infoSink.info.message(
+                            EPrefixInternalError, getLine(),
+                            "Constant folding cannot be done for \"/\"");
+                        return nullptr;
+                    }
+                }
+            }
+            break;
+
+          case EOpMatrixTimesVector:
+            {
+                if (rightNode->getBasicType() != EbtFloat)
+                {
+                    infoSink.info.message(
+                        EPrefixInternalError, getLine(),
+                        "Constant Folding cannot be done for matrix times vector");
+                    return nullptr;
+                }
+
+                const int matrixCols = getCols();
+                const int matrixRows = getRows();
+
+                tempConstArray = new TConstantUnion[matrixRows];
+
+                for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++)
+                {
+                    tempConstArray[matrixRow].setFConst(0.0f);
+                    for (int col = 0; col < matrixCols; col++)
+                    {
+                        tempConstArray[matrixRow].setFConst(
+                            tempConstArray[matrixRow].getFConst() +
+                            unionArray[col * matrixRows + matrixRow].getFConst() *
+                            rightUnionArray[col].getFConst());
+                    }
+                }
+
+                returnType = rightNode->getType();
+                returnType.setPrimarySize(static_cast<unsigned char>(matrixRows));
+
+                tempNode = new TIntermConstantUnion(tempConstArray, returnType);
+                tempNode->setLine(getLine());
+
+                return tempNode;
+            }
+
+          case EOpVectorTimesMatrix:
+            {
+                if (getType().getBasicType() != EbtFloat)
+                {
+                    infoSink.info.message(
+                        EPrefixInternalError, getLine(),
+                        "Constant Folding cannot be done for vector times matrix");
+                    return nullptr;
+                }
+
+                const int matrixCols = rightNode->getType().getCols();
+                const int matrixRows = rightNode->getType().getRows();
+
+                tempConstArray = new TConstantUnion[matrixCols];
+
+                for (int matrixCol = 0; matrixCol < matrixCols; matrixCol++)
+                {
+                    tempConstArray[matrixCol].setFConst(0.0f);
+                    for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++)
+                    {
+                        tempConstArray[matrixCol].setFConst(
+                            tempConstArray[matrixCol].getFConst() +
+                            unionArray[matrixRow].getFConst() *
+                            rightUnionArray[matrixCol * matrixRows + matrixRow].getFConst());
+                    }
+                }
+
+                returnType.setPrimarySize(static_cast<unsigned char>(matrixCols));
+            }
+            break;
+
+          case EOpLogicalAnd:
+            // this code is written for possible future use,
+            // will not get executed currently
+            {
+                tempConstArray = new TConstantUnion[objectSize];
+                for (size_t i = 0; i < objectSize; i++)
+                {
+                    tempConstArray[i] = unionArray[i] && rightUnionArray[i];
+                }
+            }
+            break;
+
+          case EOpLogicalOr:
+            // this code is written for possible future use,
+            // will not get executed currently
+            {
+                tempConstArray = new TConstantUnion[objectSize];
+                for (size_t i = 0; i < objectSize; i++)
+                {
+                    tempConstArray[i] = unionArray[i] || rightUnionArray[i];
+                }
+            }
+            break;
+
+          case EOpLogicalXor:
+            {
+                tempConstArray = new TConstantUnion[objectSize];
+                for (size_t i = 0; i < objectSize; i++)
+                {
+                    switch (getType().getBasicType())
+                    {
+                      case EbtBool:
+                        tempConstArray[i].setBConst(
+                            unionArray[i] == rightUnionArray[i] ? false : true);
+                        break;
+                      default:
+                        UNREACHABLE();
+                        break;
+                    }
+                }
+            }
+            break;
+
+          case EOpBitwiseAnd:
+            tempConstArray = new TConstantUnion[objectSize];
+            for (size_t i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] & rightUnionArray[i];
+            break;
+          case EOpBitwiseXor:
+            tempConstArray = new TConstantUnion[objectSize];
+            for (size_t i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] ^ rightUnionArray[i];
+            break;
+          case EOpBitwiseOr:
+            tempConstArray = new TConstantUnion[objectSize];
+            for (size_t i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] | rightUnionArray[i];
+            break;
+          case EOpBitShiftLeft:
+            tempConstArray = new TConstantUnion[objectSize];
+            for (size_t i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] << rightUnionArray[i];
+            break;
+          case EOpBitShiftRight:
+            tempConstArray = new TConstantUnion[objectSize];
+            for (size_t i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] >> rightUnionArray[i];
+            break;
+
+          case EOpLessThan:
+            ASSERT(objectSize == 1);
+            tempConstArray = new TConstantUnion[1];
+            tempConstArray->setBConst(*unionArray < *rightUnionArray);
+            returnType = TType(EbtBool, EbpUndefined, EvqConst);
+            break;
+
+          case EOpGreaterThan:
+            ASSERT(objectSize == 1);
+            tempConstArray = new TConstantUnion[1];
+            tempConstArray->setBConst(*unionArray > *rightUnionArray);
+            returnType = TType(EbtBool, EbpUndefined, EvqConst);
+            break;
+
+          case EOpLessThanEqual:
+            {
+                ASSERT(objectSize == 1);
+                TConstantUnion constant;
+                constant.setBConst(*unionArray > *rightUnionArray);
+                tempConstArray = new TConstantUnion[1];
+                tempConstArray->setBConst(!constant.getBConst());
+                returnType = TType(EbtBool, EbpUndefined, EvqConst);
+                break;
+            }
+
+          case EOpGreaterThanEqual:
+            {
+                ASSERT(objectSize == 1);
+                TConstantUnion constant;
+                constant.setBConst(*unionArray < *rightUnionArray);
+                tempConstArray = new TConstantUnion[1];
+                tempConstArray->setBConst(!constant.getBConst());
+                returnType = TType(EbtBool, EbpUndefined, EvqConst);
+                break;
+            }
+
+          case EOpEqual:
+            if (getType().getBasicType() == EbtStruct)
+            {
+                if (!CompareStructure(rightNode->getType(),
+                                      rightNode->getUnionArrayPointer(),
+                                      unionArray))
+                {
+                    boolNodeFlag = true;
+                }
+            }
+            else
+            {
+                for (size_t i = 0; i < objectSize; i++)
+                {
+                    if (unionArray[i] != rightUnionArray[i])
+                    {
+                        boolNodeFlag = true;
+                        break;  // break out of for loop
+                    }
+                }
+            }
+
+            tempConstArray = new TConstantUnion[1];
+            if (!boolNodeFlag)
+            {
+                tempConstArray->setBConst(true);
+            }
+            else
+            {
+                tempConstArray->setBConst(false);
+            }
+
+            tempNode = new TIntermConstantUnion(
+                tempConstArray, TType(EbtBool, EbpUndefined, EvqConst));
+            tempNode->setLine(getLine());
+
+            return tempNode;
+
+          case EOpNotEqual:
+            if (getType().getBasicType() == EbtStruct)
+            {
+                if (CompareStructure(rightNode->getType(),
+                                     rightNode->getUnionArrayPointer(),
+                                     unionArray))
+                {
+                    boolNodeFlag = true;
+                }
+            }
+            else
+            {
+                for (size_t i = 0; i < objectSize; i++)
+                {
+                    if (unionArray[i] == rightUnionArray[i])
+                    {
+                        boolNodeFlag = true;
+                        break;  // break out of for loop
+                    }
+                }
+            }
+
+            tempConstArray = new TConstantUnion[1];
+            if (!boolNodeFlag)
+            {
+                tempConstArray->setBConst(true);
+            }
+            else
+            {
+                tempConstArray->setBConst(false);
+            }
+
+            tempNode = new TIntermConstantUnion(
+                tempConstArray, TType(EbtBool, EbpUndefined, EvqConst));
+            tempNode->setLine(getLine());
+
+            return tempNode;
+
+          default:
+            infoSink.info.message(
+                EPrefixInternalError, getLine(),
+                "Invalid operator for constant folding");
+            return nullptr;
+        }
+        tempNode = new TIntermConstantUnion(tempConstArray, returnType);
+        tempNode->setLine(getLine());
+
+        return tempNode;
+    }
+    else if (op == EOpAny || op == EOpAll || op == EOpLength)
     {
         // Do operations where the return type is different from the operand type.