diff --git a/Test/baseResults/300.frag.out b/Test/baseResults/300.frag.out
index 11567cabad6f897c23a777657d8f5c90ae671f27..29d911ea0016d545946460a1f10b4ecf693ddbc6 100644
--- a/Test/baseResults/300.frag.out
+++ b/Test/baseResults/300.frag.out
@@ -33,8 +33,8 @@ ERROR: 0:122: '=' : can't use with samplers or structs containing samplers
 ERROR: 0:123: '==' : can't use with samplers or structs containing samplers 
 ERROR: 0:129: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]
 ERROR: 0:129: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]
-ERROR: 0:138: 'imageBuffer' : Reserved word. 
-ERROR: 0:138: '' :  syntax error
+ERROR: 0:148: 'imageBuffer' : Reserved word. 
+ERROR: 0:148: '' :  syntax error
 ERROR: 36 compilation errors.  No code generated.
 
 
@@ -292,6 +292,64 @@ ERROR: node is still EOpNull!
 0:135        'p' (lowp float)
 0:135        Constant:
 0:135          0.389418
+0:136      add second child into first child (lowp float)
+0:136        'p' (lowp float)
+0:136        Constant:
+0:136          5.000000
+0:137      add second child into first child (lowp float)
+0:137        'p' (lowp float)
+0:137        Constant:
+0:137          13.000000
+0:138      Sequence
+0:138        move second child to first child (lowp 3-component vector of float)
+0:138          'c3' (lowp 3-component vector of float)
+0:138          Constant:
+0:138            -15.000000
+0:138            -2.000000
+0:138            39.000000
+0:139      add second child into first child (lowp 3-component vector of float)
+0:139        'c3' (lowp 3-component vector of float)
+0:139        Constant:
+0:139          -1.000000
+0:139          -2.000000
+0:139          -3.000000
+0:140      add second child into first child (lowp 3-component vector of float)
+0:140        'c3' (lowp 3-component vector of float)
+0:140        Constant:
+0:140          1.000000
+0:140          2.000000
+0:140          3.000000
+0:141      Sequence
+0:141        move second child to first child (lowp 2-component vector of float)
+0:141          'c2' (lowp 2-component vector of float)
+0:141          Constant:
+0:141            1.000000
+0:141            -3.000000
+0:142      add second child into first child (lowp 2-component vector of float)
+0:142        'c2' (lowp 2-component vector of float)
+0:142        Constant:
+0:142          1.000000
+0:142          -3.000000
+0:143      add second child into first child (lowp 2-component vector of float)
+0:143        'c2' (lowp 2-component vector of float)
+0:143        Constant:
+0:143          3.000000
+0:143          -8.544004
+0:144      add second child into first child (lowp 2-component vector of float)
+0:144        'c2' (lowp 2-component vector of float)
+0:144        Constant:
+0:144          0.000000
+0:144          0.000000
+0:145      Sequence
+0:145        move second child to first child (lowp 3X2 matrix of float)
+0:145          'm32' (lowp 3X2 matrix of float)
+0:145          Constant:
+0:145            10.000000
+0:145            15.000000
+0:145            14.000000
+0:145            21.000000
+0:145            22.000000
+0:145            33.000000
 0:?   Linker Objects
 0:?     's2D' (uniform lowp sampler2D)
 0:?     's3D' (uniform lowp sampler3D)
diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp
index 48be7d37608eb1ba2124d4e4cbce32f4c3e41034..4d0b685902c209defd6c3277eeebacd80711acbc 100644
--- a/glslang/MachineIndependent/Constant.cpp
+++ b/glslang/MachineIndependent/Constant.cpp
@@ -300,13 +300,17 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
 TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
 {
     // First, size the result, which is mostly the same as the argument's size,
-    // but not always.
+    // but not always, and classify what is componentwise.
+    // Also, eliminate cases that can't be compile-time constant.
     int resultSize;
+    bool componentWise = true;
+
     switch (op) {
     case EOpDeterminant:
     case EOpAny:
     case EOpAll:
     case EOpLength:
+        componentWise = false;
         resultSize = 1;
         break;
 
@@ -318,25 +322,33 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
     case EOpPackSnorm2x16:
     case EOpPackUnorm2x16:
     case EOpPackHalf2x16:
+        componentWise = false;
         resultSize = 1;
         break;
 
     case EOpUnpackSnorm2x16:
     case EOpUnpackUnorm2x16:
     case EOpUnpackHalf2x16:
+        componentWise = false;
         resultSize = 2;
         break;
 
+    case EOpNormalize:
+        componentWise = false;
+        resultSize = getType().getObjectSize();
+        break;
+
     default:
         resultSize = getType().getObjectSize();
         break;
     }
-    TConstUnionArray newConstArray(resultSize);
 
-    const TConstUnionArray unionArray = getConstArray();
+    // Set up for processing
+    TConstUnionArray newConstArray(resultSize);
+    const TConstUnionArray& unionArray = getConstArray();
+    int objectSize = getType().getObjectSize();
 
     // Process non-component-wise operations
-    int objectSize = getType().getObjectSize();
     switch (op) {
     case EOpLength:
     case EOpNormalize:
@@ -353,10 +365,35 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
         }
         break;
     }
+
+    // TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out
+
+    case EOpPackSnorm2x16:
+    case EOpPackUnorm2x16:
+    case EOpPackHalf2x16:
+
+    case EOpUnpackSnorm2x16:
+    case EOpUnpackUnorm2x16:
+    case EOpUnpackHalf2x16:
+
+    case EOpDeterminant:
+    case EOpMatrixInverse:
+    case EOpTranspose:
+
+    case EOpAny:
+    case EOpAll:
+        return 0;
+    
     default:
+        assert(componentWise);
         break;
     }
 
+    // Turn off the componentwise loop
+    if (! componentWise)
+        objectSize = 0;
+
+    // Process component-wise operations
     for (int i = 0; i < objectSize; i++) {
         switch (op) {
         case EOpNegative:
@@ -405,11 +442,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
             newConstArray[i].setDConst(atan(unionArray[i].getDConst()));
             break;
 
-        case EOpLength:
-        case EOpNormalize:
-            // handled above as special case
-            break;
-
         case EOpDPdx:
         case EOpDPdy:
         case EOpFwidth:
@@ -512,20 +544,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
         case EOpIntBitsToFloat:
         case EOpUintBitsToFloat:
 
-        case EOpPackSnorm2x16:
-        case EOpUnpackSnorm2x16:
-        case EOpPackUnorm2x16:
-        case EOpUnpackUnorm2x16:
-        case EOpPackHalf2x16:
-        case EOpUnpackHalf2x16:
-
-        case EOpDeterminant:
-        case EOpMatrixInverse:
-        case EOpTranspose:
-
-        case EOpAny:
-        case EOpAll:
-
         default:
             return 0;
         }