Constant folding: Correct result type of non-square matrix folding.

This also made the function easier to read by identifying
left and right operands more clearly.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index e1babc1..a2e8a9e 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -229,7 +229,7 @@
 spv::Decoration TranslatePrecisionDecoration(const glslang::TType& type)
 {
     switch (type.getQualifier().precision) {
-    case glslang::EpqLow:    return spv::DecorationRelaxedPrecision; // TODO: Map instead to 16-bit types?
+    case glslang::EpqLow:    return spv::DecorationRelaxedPrecision;
     case glslang::EpqMedium: return spv::DecorationRelaxedPrecision;
     case glslang::EpqHigh:   return spv::NoPrecision;
     default:
diff --git a/Test/baseResults/constFold.frag.out b/Test/baseResults/constFold.frag.out
index bd6e040..c03d865 100644
--- a/Test/baseResults/constFold.frag.out
+++ b/Test/baseResults/constFold.frag.out
@@ -257,6 +257,19 @@
 0:120                1.000000
 0:120          Constant:
 0:120            3 (const int)
+0:126  Function Definition: foo3( (global void)
+0:126    Function Parameters: 
+0:128    Sequence
+0:128      Sequence
+0:128        move second child to first child (temp 3X2 matrix of float)
+0:128          'r32' (temp 3X2 matrix of float)
+0:128          Constant:
+0:128            43.000000
+0:128            64.000000
+0:128            51.000000
+0:128            76.000000
+0:128            59.000000
+0:128            88.000000
 0:?   Linker Objects
 0:?     'a' (const int)
 0:?       1 (const int)
@@ -331,6 +344,18 @@
 0:?       4.000000
 0:?       5.000000
 0:?     'a4' (global 2-element array of float)
+0:?     'mm2' (const 2X2 matrix of float)
+0:?       1.000000
+0:?       2.000000
+0:?       3.000000
+0:?       4.000000
+0:?     'mm32' (const 3X2 matrix of float)
+0:?       10.000000
+0:?       11.000000
+0:?       12.000000
+0:?       13.000000
+0:?       14.000000
+0:?       15.000000
 
 
 Linked fragment stage:
@@ -584,6 +609,19 @@
 0:120                1.000000
 0:120          Constant:
 0:120            3 (const int)
+0:126  Function Definition: foo3( (global void)
+0:126    Function Parameters: 
+0:128    Sequence
+0:128      Sequence
+0:128        move second child to first child (temp 3X2 matrix of float)
+0:128          'r32' (temp 3X2 matrix of float)
+0:128          Constant:
+0:128            43.000000
+0:128            64.000000
+0:128            51.000000
+0:128            76.000000
+0:128            59.000000
+0:128            88.000000
 0:?   Linker Objects
 0:?     'a' (const int)
 0:?       1 (const int)
@@ -658,4 +696,16 @@
 0:?       4.000000
 0:?       5.000000
 0:?     'a4' (global 2-element array of float)
+0:?     'mm2' (const 2X2 matrix of float)
+0:?       1.000000
+0:?       2.000000
+0:?       3.000000
+0:?       4.000000
+0:?     'mm32' (const 3X2 matrix of float)
+0:?       10.000000
+0:?       11.000000
+0:?       12.000000
+0:?       13.000000
+0:?       14.000000
+0:?       15.000000
 
diff --git a/Test/constFold.frag b/Test/constFold.frag
index ae0817a..81c718c 100644
--- a/Test/constFold.frag
+++ b/Test/constFold.frag
@@ -119,3 +119,11 @@
     float f = vec4(7.8 < 2.4 ? -1.333 : 1.444).a;
     f = vec4(inv.x < 2.4 ? -1.0 : 1.0).a;  // not folded, ensuring no propagation
 }
+
+const mat2 mm2 = mat2(1.0, 2.0, 3.0, 4.0);

+const mat3x2 mm32 = mat3x2(10.0, 11.0, 12.0, 13.0, 14.0, 15.0);

+

+void foo3()

+{

+    mat3x2 r32 = mm2 * mm32;

+}

diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h
index 542f8f3..4ad7772 100644
--- a/glslang/Include/revision.h
+++ b/glslang/Include/revision.h
@@ -2,5 +2,5 @@
 // For the version, it uses the latest git tag followed by the number of commits.
 // For the date, it uses the current date (when then script is run).
 
-#define GLSLANG_REVISION "SPIRV99.845"
-#define GLSLANG_DATE "13-Dec-2015"
+#define GLSLANG_REVISION "SPIRV99.849"
+#define GLSLANG_DATE "16-Dec-2015"
diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp
index 6a797f0..a0bb8de 100644
--- a/glslang/MachineIndependent/Constant.cpp
+++ b/glslang/MachineIndependent/Constant.cpp
@@ -81,11 +81,12 @@
 //
 
 //
-// Do folding between a pair of nodes
+// Do folding between a pair of nodes.
+// 'this' is the left-hand operand and 'rightConstantNode' is the right-hand operand.
 //
 // Returns a new node representing the result.
 //
-TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* constantNode) const
+TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* rightConstantNode) const
 {
     // For most cases, the return type matches the argument type, so set that
     // up and just code to exceptions below.
@@ -96,37 +97,37 @@
     // A pair of nodes is to be folded together
     //
 
-    const TIntermConstantUnion *node = constantNode->getAsConstantUnion();
-    TConstUnionArray unionArray = getConstArray();
-    TConstUnionArray rightUnionArray = node->getConstArray();
+    const TIntermConstantUnion *rightNode = rightConstantNode->getAsConstantUnion();
+    TConstUnionArray leftUnionArray = getConstArray();
+    TConstUnionArray rightUnionArray = rightNode->getConstArray();
 
     // Figure out the size of the result
     int newComps;
     int constComps;
     switch(op) {
     case EOpMatrixTimesMatrix:
-        newComps = getMatrixRows() * node->getMatrixCols();
+        newComps = rightNode->getMatrixCols() * getMatrixRows();
         break;
     case EOpMatrixTimesVector:
         newComps = getMatrixRows();
         break;
     case EOpVectorTimesMatrix:
-        newComps = node->getMatrixCols();
+        newComps = rightNode->getMatrixCols();
         break;
     default:
         newComps = getType().computeNumComponents();
-        constComps = constantNode->getType().computeNumComponents();
+        constComps = rightConstantNode->getType().computeNumComponents();
         if (constComps == 1 && newComps > 1) {
             // for a case like vec4 f = vec4(2,3,4,5) + 1.2;
-            TConstUnionArray smearedArray(newComps, node->getConstArray()[0]);
+            TConstUnionArray smearedArray(newComps, rightNode->getConstArray()[0]);
             rightUnionArray = smearedArray;
         } else if (constComps > 1 && newComps == 1) {
             // for a case like vec4 f = 1.2 + vec4(2,3,4,5);            
             newComps = constComps;
-            rightUnionArray = node->getConstArray();
+            rightUnionArray = rightNode->getConstArray();
             TConstUnionArray smearedArray(newComps, getConstArray()[0]);
-            unionArray = smearedArray;
-            returnType.shallowCopy(node->getType());
+            leftUnionArray = smearedArray;
+            returnType.shallowCopy(rightNode->getType());
         }
         break;
     }
@@ -137,52 +138,52 @@
     switch(op) {
     case EOpAdd:
         for (int i = 0; i < newComps; i++)
-            newConstArray[i] = unionArray[i] + rightUnionArray[i];
+            newConstArray[i] = leftUnionArray[i] + rightUnionArray[i];
         break;
     case EOpSub:
         for (int i = 0; i < newComps; i++)
-            newConstArray[i] = unionArray[i] - rightUnionArray[i];
+            newConstArray[i] = leftUnionArray[i] - rightUnionArray[i];
         break;
 
     case EOpMul:
     case EOpVectorTimesScalar:
     case EOpMatrixTimesScalar:
         for (int i = 0; i < newComps; i++)
-            newConstArray[i] = unionArray[i] * rightUnionArray[i];
+            newConstArray[i] = leftUnionArray[i] * rightUnionArray[i];
         break;
     case EOpMatrixTimesMatrix:
         for (int row = 0; row < getMatrixRows(); row++) {
-            for (int column = 0; column < node->getMatrixCols(); column++) {
+            for (int column = 0; column < rightNode->getMatrixCols(); column++) {
                 double sum = 0.0f;
-                for (int i = 0; i < node->getMatrixRows(); i++)
-                    sum += unionArray[i * getMatrixRows() + row].getDConst() * rightUnionArray[column * node->getMatrixRows() + i].getDConst();
+                for (int i = 0; i < rightNode->getMatrixRows(); i++)
+                    sum += leftUnionArray[i * getMatrixRows() + row].getDConst() * rightUnionArray[column * rightNode->getMatrixRows() + i].getDConst();
                 newConstArray[column * getMatrixRows() + row].setDConst(sum);
             }
         }
-        returnType.shallowCopy(TType(getType().getBasicType(), EvqConst, 0, getMatrixRows(), node->getMatrixCols()));
+        returnType.shallowCopy(TType(getType().getBasicType(), EvqConst, 0, rightNode->getMatrixCols(), getMatrixRows()));
         break;
     case EOpDiv:
         for (int i = 0; i < newComps; i++) {
             switch (getType().getBasicType()) {
             case EbtDouble:
             case EbtFloat:
-                newConstArray[i].setDConst(unionArray[i].getDConst() / rightUnionArray[i].getDConst());
+                newConstArray[i].setDConst(leftUnionArray[i].getDConst() / rightUnionArray[i].getDConst());
                 break;
 
             case EbtInt:
                 if (rightUnionArray[i] == 0)
                     newConstArray[i].setIConst(0x7FFFFFFF);
-                else if (rightUnionArray[i].getIConst() == -1 && unionArray[i].getIConst() == 0x80000000)
+                else if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == 0x80000000)
                     newConstArray[i].setIConst(0x80000000);
                 else
-                    newConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst());
+                    newConstArray[i].setIConst(leftUnionArray[i].getIConst() / rightUnionArray[i].getIConst());
                 break;
 
             case EbtUint:
                 if (rightUnionArray[i] == 0) {
                     newConstArray[i].setUConst(0xFFFFFFFF);
                 } else
-                    newConstArray[i].setUConst(unionArray[i].getUConst() / rightUnionArray[i].getUConst());
+                    newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst());
                 break;
             default:
                 return 0;
@@ -193,8 +194,8 @@
     case EOpMatrixTimesVector:
         for (int i = 0; i < getMatrixRows(); i++) {
             double sum = 0.0f;
-            for (int j = 0; j < node->getVectorSize(); j++) {
-                sum += unionArray[j*getMatrixRows() + i].getDConst() * rightUnionArray[j].getDConst();
+            for (int j = 0; j < rightNode->getVectorSize(); j++) {
+                sum += leftUnionArray[j*getMatrixRows() + i].getDConst() * rightUnionArray[j].getDConst();
             }
             newConstArray[i].setDConst(sum);
         }
@@ -203,89 +204,89 @@
         break;
 
     case EOpVectorTimesMatrix:
-        for (int i = 0; i < node->getMatrixCols(); i++) {
+        for (int i = 0; i < rightNode->getMatrixCols(); i++) {
             double sum = 0.0f;
             for (int j = 0; j < getVectorSize(); j++)
-                sum += unionArray[j].getDConst() * rightUnionArray[i*node->getMatrixRows() + j].getDConst();
+                sum += leftUnionArray[j].getDConst() * rightUnionArray[i*rightNode->getMatrixRows() + j].getDConst();
             newConstArray[i].setDConst(sum);
         }
 
-        returnType.shallowCopy(TType(getBasicType(), EvqConst, node->getMatrixCols()));
+        returnType.shallowCopy(TType(getBasicType(), EvqConst, rightNode->getMatrixCols()));
         break;
 
     case EOpMod:
         for (int i = 0; i < newComps; i++) {
             if (rightUnionArray[i] == 0)
-                newConstArray[i] = unionArray[i];
+                newConstArray[i] = leftUnionArray[i];
             else
-                newConstArray[i] = unionArray[i] % rightUnionArray[i];
+                newConstArray[i] = leftUnionArray[i] % rightUnionArray[i];
         }
         break;
 
     case EOpRightShift:
         for (int i = 0; i < newComps; i++)
-            newConstArray[i] = unionArray[i] >> rightUnionArray[i];
+            newConstArray[i] = leftUnionArray[i] >> rightUnionArray[i];
         break;
 
     case EOpLeftShift:
         for (int i = 0; i < newComps; i++)
-            newConstArray[i] = unionArray[i] << rightUnionArray[i];
+            newConstArray[i] = leftUnionArray[i] << rightUnionArray[i];
         break;
 
     case EOpAnd:
         for (int i = 0; i < newComps; i++)
-            newConstArray[i] = unionArray[i] & rightUnionArray[i];
+            newConstArray[i] = leftUnionArray[i] & rightUnionArray[i];
         break;
     case EOpInclusiveOr:
         for (int i = 0; i < newComps; i++)
-            newConstArray[i] = unionArray[i] | rightUnionArray[i];
+            newConstArray[i] = leftUnionArray[i] | rightUnionArray[i];
         break;
     case EOpExclusiveOr:
         for (int i = 0; i < newComps; i++)
-            newConstArray[i] = unionArray[i] ^ rightUnionArray[i];
+            newConstArray[i] = leftUnionArray[i] ^ rightUnionArray[i];
         break;
 
     case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
         for (int i = 0; i < newComps; i++)
-            newConstArray[i] = unionArray[i] && rightUnionArray[i];
+            newConstArray[i] = leftUnionArray[i] && rightUnionArray[i];
         break;
 
     case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
         for (int i = 0; i < newComps; i++)
-            newConstArray[i] = unionArray[i] || rightUnionArray[i];
+            newConstArray[i] = leftUnionArray[i] || rightUnionArray[i];
         break;
 
     case EOpLogicalXor:
         for (int i = 0; i < newComps; i++) {
             switch (getType().getBasicType()) {
-            case EbtBool: newConstArray[i].setBConst((unionArray[i] == rightUnionArray[i]) ? false : true); break;
+            case EbtBool: newConstArray[i].setBConst((leftUnionArray[i] == rightUnionArray[i]) ? false : true); break;
             default: assert(false && "Default missing");
             }
         }
         break;
 
     case EOpLessThan:
-        newConstArray[0].setBConst(unionArray[0] < rightUnionArray[0]);
+        newConstArray[0].setBConst(leftUnionArray[0] < rightUnionArray[0]);
         returnType.shallowCopy(constBool);
         break;
     case EOpGreaterThan:
-        newConstArray[0].setBConst(unionArray[0] > rightUnionArray[0]);
+        newConstArray[0].setBConst(leftUnionArray[0] > rightUnionArray[0]);
         returnType.shallowCopy(constBool);
         break;
     case EOpLessThanEqual:
-        newConstArray[0].setBConst(! (unionArray[0] > rightUnionArray[0]));
+        newConstArray[0].setBConst(! (leftUnionArray[0] > rightUnionArray[0]));
         returnType.shallowCopy(constBool);
         break;
     case EOpGreaterThanEqual:
-        newConstArray[0].setBConst(! (unionArray[0] < rightUnionArray[0]));
+        newConstArray[0].setBConst(! (leftUnionArray[0] < rightUnionArray[0]));
         returnType.shallowCopy(constBool);
         break;
     case EOpEqual:
-        newConstArray[0].setBConst(node->getConstArray() == unionArray);
+        newConstArray[0].setBConst(rightNode->getConstArray() == leftUnionArray);
         returnType.shallowCopy(constBool);
         break;
     case EOpNotEqual:
-        newConstArray[0].setBConst(node->getConstArray() != unionArray);
+        newConstArray[0].setBConst(rightNode->getConstArray() != leftUnionArray);
         returnType.shallowCopy(constBool);
         break;