Support multiple swizzled out operands (#2175)

Swizzled out operands were added in bbbd9a2a. This was sufficient
for most tests, but we ran into problems with umulExtended and
imulExtended, which have two.

This CL converts the tracking values to vectors so multiple operands
can be supported.

Test: KHR-GLES31.core.shader_bitfield_operation.*
Test: ctest
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 51a7618..071dad3 100644
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -2357,10 +2357,10 @@
         spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
 
     spv::Id result = spv::NoResult;
-    spv::Id invertedType = spv::NoType;       // to use to override the natural type of the node
-    spv::Builder::AccessChain complexLvalue;  // for holding swizzling l-values too complex for SPIR-V,
-                                              // for at out parameter
-    spv::Id temporaryLvalue = spv::NoResult;  // temporary to pass, as proxy for complexLValue
+    spv::Id invertedType = spv::NoType;                     // to use to override the natural type of the node
+    std::vector<spv::Builder::AccessChain> complexLvalues;  // for holding swizzling l-values too complex for
+                                                            // SPIR-V, for an out parameter
+    std::vector<spv::Id> temporaryLvalues;                  // temporaries to pass, as proxies for complexLValues
 
     auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ?
         invertedType :
@@ -2976,10 +2976,10 @@
                 // reduce to a simple access chain.  So, we need a temporary vector to
                 // receive the result, and must later swizzle that into the original
                 // l-value.
-                complexLvalue = builder.getAccessChain();
-                temporaryLvalue = builder.createVariable(spv::StorageClassFunction,
-                    builder.accessChainGetInferredType(), "swizzleTemp");
-                operands.push_back(temporaryLvalue);
+                complexLvalues.push_back(builder.getAccessChain());
+                temporaryLvalues.push_back(builder.createVariable(spv::StorageClassFunction,
+                    builder.accessChainGetInferredType(), "swizzleTemp"));
+                operands.push_back(temporaryLvalues.back());
             } else {
                 operands.push_back(builder.accessChainGetLValue());
             }
@@ -3074,11 +3074,13 @@
             result = createMiscOperation(node->getOp(), precision, resultType(), operands, node->getBasicType());
             break;
         }
+
         if (invertedType != spv::NoResult)
             result = createInvertedSwizzle(precision, *glslangOperands[0]->getAsBinaryNode(), result);
-        else if (temporaryLvalue != spv::NoResult) {
-            builder.setAccessChain(complexLvalue);
-            builder.accessChainStore(builder.createLoad(temporaryLvalue));
+
+        for (unsigned int i = 0; i < temporaryLvalues.size(); ++i) {
+            builder.setAccessChain(complexLvalues[i]);
+            builder.accessChainStore(builder.createLoad(temporaryLvalues[i]));
         }
     }