SPV: RelaxedPrecision: Generalize fix #2293 to cover more operations.

This simplifies and enforces use of precision in many more places,
to help avoid accidental loss of RelaxedPrecision through intermediate
operations. Known fixes are:
- ?:
- function return values with mis-matched precision
- precision of function return values when a copy was needed to fix types
diff --git a/SPIRV/spvIR.h b/SPIRV/spvIR.h
index 6146518..868b9bf 100755
--- a/SPIRV/spvIR.h
+++ b/SPIRV/spvIR.h
@@ -352,13 +352,27 @@
     const std::vector<Block*>& getBlocks() const { return blocks; }
     void addLocalVariable(std::unique_ptr<Instruction> inst);
     Id getReturnType() const { return functionInstruction.getTypeId(); }
+    void setReturnPrecision(Decoration precision)
+    {
+        if (precision == DecorationRelaxedPrecision)
+            reducedPrecisionReturn = true;
+    }
+    Decoration getReturnPrecision() const
+        { return reducedPrecisionReturn ? DecorationRelaxedPrecision : NoPrecision; }
 
     void setImplicitThis() { implicitThis = true; }
     bool hasImplicitThis() const { return implicitThis; }
 
-    void addReducedPrecisionParam(int p) { reducedPrecisionParams.insert(p); }
-    bool isReducedPrecisionParam(int p) const
-        { return reducedPrecisionParams.find(p) != reducedPrecisionParams.end(); }
+    void addParamPrecision(unsigned param, Decoration precision)
+    {
+        if (precision == DecorationRelaxedPrecision)
+            reducedPrecisionParams.insert(param);
+    }
+    Decoration getParamPrecision(unsigned param) const
+    {
+        return reducedPrecisionParams.find(param) != reducedPrecisionParams.end() ?
+            DecorationRelaxedPrecision : NoPrecision;
+    }
 
     void dump(std::vector<unsigned int>& out) const
     {
@@ -384,6 +398,7 @@
     std::vector<Instruction*> parameterInstructions;
     std::vector<Block*> blocks;
     bool implicitThis;  // true if this is a member function expecting to be passed a 'this' as the first argument
+    bool reducedPrecisionReturn;
     std::set<int> reducedPrecisionParams;  // list of parameter indexes that need a relaxed precision arg
 };
 
@@ -445,7 +460,8 @@
 // - the OpFunction instruction
 // - all the OpFunctionParameter instructions
 __inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, Module& parent)
-    : parent(parent), functionInstruction(id, resultType, OpFunction), implicitThis(false)
+    : parent(parent), functionInstruction(id, resultType, OpFunction), implicitThis(false),
+      reducedPrecisionReturn(false)
 {
     // OpFunction
     functionInstruction.addImmediateOperand(FunctionControlMaskNone);