SPV: Partially address #2293: correct "const in" precision matching.

Track whether formal parameters declare reduced precision and match
that with arguments, and if they differ, make a copy to promote the
precision.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index b63d901..fb36212 100644
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -5346,13 +5346,21 @@
             }
             ++lValueCount;
         } else {
+            const bool argIsRelaxedPrecision = TranslatePrecisionDecoration(*argTypes[a]) ==
+                spv::DecorationRelaxedPrecision;
             // process r-value, which involves a copy for a type mismatch
-            if (function->getParamType(a) != convertGlslangToSpvType(*argTypes[a])) {
+            if (function->getParamType(a) != convertGlslangToSpvType(*argTypes[a]) ||
+                argIsRelaxedPrecision != function->isReducedPrecisionParam(a))
+            {
                 spv::Id argCopy = builder.createVariable(spv::StorageClassFunction, function->getParamType(a), "arg");
+                if (function->isReducedPrecisionParam(a))
+                    builder.setPrecision(argCopy, spv::DecorationRelaxedPrecision);
                 builder.clearAccessChain();
                 builder.setAccessChainLValue(argCopy);
                 multiTypeStore(*argTypes[a], rValues[rValueCount]);
                 arg = builder.createLoad(argCopy);
+                if (function->isReducedPrecisionParam(a))
+                    builder.setPrecision(arg, spv::DecorationRelaxedPrecision);
             } else
                 arg = rValues[rValueCount];
             ++rValueCount;