Fix #1843: Handle built-in function output parameters to a swizzled arg

In GLSL/HLSL/AST,  v.zyx is an l-value, but not in SPIR-V, which cannot represent it.
So, a temporary is used instead.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index b2a93cf..ccf112d 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -2277,7 +2277,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::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
+
     auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ? invertedType : convertGlslangToSpvType(node->getType()); };
 
     // try texturing
@@ -2727,6 +2730,10 @@
 
                 // Does it need a swizzle inversion?  If so, evaluation is inverted;
                 // operate first on the swizzle base, then apply the swizzle.
+                // That is, we transform
+                //
+                //    interpolate(v.zy)  ->  interpolate(v).zy
+                //
                 if (glslangOperands[0]->getAsOperator() &&
                     glslangOperands[0]->getAsOperator()->getOp() == glslang::EOpVectorSwizzle)
                     invertedType = convertGlslangToSpvType(glslangOperands[0]->getAsBinaryNode()->getLeft()->getType());
@@ -2819,8 +2826,19 @@
         }
 #endif
 
+        // for l-values, pass the address, for r-values, pass the value
         if (lvalue) {
-            operands.push_back(builder.accessChainGetLValue());
+            if (invertedType == spv::NoType && !builder.isSpvLvalue()) {
+                // SPIR-V cannot represent an l-value containing a swizzle that doesn't
+                // 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);
+            } else {
+                operands.push_back(builder.accessChainGetLValue());
+            }
             lvalueCoherentFlags = builder.getAccessChain().coherentFlags;
             lvalueCoherentFlags |= TranslateCoherent(glslangOperands[arg]->getAsTyped()->getType());
         } else {
@@ -2883,8 +2901,12 @@
             result = createMiscOperation(node->getOp(), precision, resultType(), operands, node->getBasicType());
             break;
         }
-        if (invertedType)
+        if (invertedType != spv::NoResult)
             result = createInvertedSwizzle(precision, *glslangOperands[0]->getAsBinaryNode(), result);
+        else if (temporaryLvalue != spv::NoResult) {
+            builder.setAccessChain(complexLvalue);
+            builder.accessChainStore(builder.createLoad(temporaryLvalue));
+        }
     }
 
     if (noReturnValue)