Fix precision propagation around shifts
Fixes #2541
diff --git a/Test/baseResults/spv.precision.frag.out b/Test/baseResults/spv.precision.frag.out
index 973147d..1d31230 100644
--- a/Test/baseResults/spv.precision.frag.out
+++ b/Test/baseResults/spv.precision.frag.out
@@ -1,14 +1,15 @@
spv.precision.frag
// Module Version 10000
// Generated by (magic number): 8000a
-// Id's are bound by 146
+// Id's are bound by 165
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
- EntryPoint Fragment 4 "main" 23 62 64 76 119
+ EntryPoint Fragment 4 "main" 23 62 64 76 119 149
ExecutionMode 4 OriginUpperLeft
Source ESSL 310
+ SourceExtension "GL_OES_sample_variables"
Name 4 "main"
Name 12 "foo(vf3;"
Name 11 "mv3"
@@ -33,6 +34,7 @@
MemberName 117(S) 0 "a"
MemberName 117(S) 1 "b"
Name 119 "s"
+ Name 149 "gl_SampleMaskIn"
Decorate 12(foo(vf3;) RelaxedPrecision
Decorate 11(mv3) RelaxedPrecision
Decorate 23(highfin) Location 2
@@ -97,6 +99,15 @@
Decorate 143 RelaxedPrecision
Decorate 144 RelaxedPrecision
Decorate 145 RelaxedPrecision
+ Decorate 149(gl_SampleMaskIn) Flat
+ Decorate 149(gl_SampleMaskIn) BuiltIn SampleMask
+ Decorate 153 RelaxedPrecision
+ Decorate 156 RelaxedPrecision
+ Decorate 159 RelaxedPrecision
+ Decorate 160 RelaxedPrecision
+ Decorate 162 RelaxedPrecision
+ Decorate 163 RelaxedPrecision
+ Decorate 164 RelaxedPrecision
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
@@ -147,6 +158,11 @@
133: 6(float) Constant 1082549862
138: 6(float) Constant 1073741824
142: 6(float) Constant 1077936128
+ 146: 95(int) Constant 1
+ 147: TypeArray 39(int) 146
+ 148: TypePointer Input 147
+149(gl_SampleMaskIn): 148(ptr) Variable Input
+ 150: TypePointer Input 39(int)
4(main): 2 Function None 3
5: Label
41(sum): 40(ptr) Variable Function
@@ -156,6 +172,7 @@
72(local_highp): 71(ptr) Variable Function
108(param): 16(ptr) Variable Function
135: 71(ptr) Variable Function
+ 156: 71(ptr) Variable Function
44: 39(int) Load 43(uniform_medium)
46: 39(int) Load 45(uniform_high)
47: 39(int) IAdd 44 46
@@ -249,6 +266,26 @@
137: Label
145: 21(fvec4) Load 135
Store 76(mediumfout) 145
+ 151: 150(ptr) AccessChain 149(gl_SampleMaskIn) 120
+ 152: 39(int) Load 151
+ 153: 39(int) Load 43(uniform_medium)
+ 154: 39(int) ShiftRightArithmetic 152 153
+ 155: 14(bool) SGreaterThan 154 120
+ SelectionMerge 158 None
+ BranchConditional 155 157 161
+ 157: Label
+ 159: 21(fvec4) Load 76(mediumfout)
+ 160: 21(fvec4) VectorTimesScalar 159 138
+ Store 156 160
+ Branch 158
+ 161: Label
+ 162: 21(fvec4) Load 76(mediumfout)
+ 163: 21(fvec4) VectorTimesScalar 162 142
+ Store 156 163
+ Branch 158
+ 158: Label
+ 164: 21(fvec4) Load 156
+ Store 76(mediumfout) 164
Return
FunctionEnd
12(foo(vf3;): 9(fvec2) Function None 10
diff --git a/Test/spv.precision.frag b/Test/spv.precision.frag
index 463afdf..d887ce9 100644
--- a/Test/spv.precision.frag
+++ b/Test/spv.precision.frag
@@ -1,4 +1,5 @@
#version 310 es
+#extension GL_OES_sample_variables : enable
precision mediump float;
in lowp float lowfin;
in mediump float mediumfin;
@@ -59,4 +60,5 @@
mediumfout *= s.b;
mediumfout = ((mediumfin * mediumfin > 4.2) ? 2.0 * mediumfout : 3.0 * mediumfout);
+ mediumfout = ((gl_SampleMaskIn[0] >> uniform_medium > 0) ? 2.0 * mediumfout : 3.0 * mediumfout);
}
diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp
index cadf6f3..d1123d4 100644
--- a/glslang/MachineIndependent/Intermediate.cpp
+++ b/glslang/MachineIndependent/Intermediate.cpp
@@ -3776,11 +3776,16 @@
{
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
- getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision);
- if (getQualifier().precision != EpqNone) {
- left->propagatePrecision(getQualifier().precision);
- right->propagatePrecision(getQualifier().precision);
- }
+ if (op == EOpRightShift || op == EOpLeftShift) {
+ // For shifts get precision from left side only and thus no need to propagate
+ getQualifier().precision = left->getQualifier().precision;
+ } else {
+ getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision);
+ if (getQualifier().precision != EpqNone) {
+ left->propagatePrecision(getQualifier().precision);
+ right->propagatePrecision(getQualifier().precision);
+ }
+ }
}
}