summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2021-04-20 14:07:40 -0700
committerMarge Bot <emma+marge@anholt.net>2022-01-26 19:31:54 +0000
commit30ec7125e83f04edc3a39c517a0526b91ce85854 (patch)
tree4aa6f450e0101dc1d613082b266d4b99e091e72b
parentd2156146a241b69655a07fcf969702dd10fc2c67 (diff)
glsl-1.30: Test some logic joined comparisons with NaN
These try to reproduce some possible errors introduced by replacing the logic joined comparisons with either min or max. Without proper conditioning, the min or max could be repalced by an fsat that would produce incorrect results. Both of these tests fail in mesa!10012 without the corrections suggested by Rhys. Acked-by: Emma Anholt <emma@anholt.net> Part-of: <https://gitlab.freedesktop.org/mesa/piglit/-/merge_requests/514>
-rw-r--r--tests/spec/glsl-1.30/execution/fs-logic-joined-comparisons-with-nan.shader_test51
-rw-r--r--tests/spec/glsl-1.30/execution/fs-logic-joined-comparisons-with-nan2.shader_test52
2 files changed, 103 insertions, 0 deletions
diff --git a/tests/spec/glsl-1.30/execution/fs-logic-joined-comparisons-with-nan.shader_test b/tests/spec/glsl-1.30/execution/fs-logic-joined-comparisons-with-nan.shader_test
new file mode 100644
index 000000000..0d9f05409
--- /dev/null
+++ b/tests/spec/glsl-1.30/execution/fs-logic-joined-comparisons-with-nan.shader_test
@@ -0,0 +1,51 @@
+[require]
+GLSL >= 1.30
+
+[vertex shader passthrough]
+
+[fragment shader]
+#version 130
+
+uniform float zero = 0.0;
+uniform float also_zero = 0.0;
+uniform float billion = 1000000000.0;
+uniform float flt_max = 3.40282347E+38;
+
+out vec4 piglit_fragcolor;
+
+void main()
+{
+ float inf = flt_max * flt_max;
+ float also_inf = flt_max * billion;
+
+ /* Trying very hard to trigger a potential sequence of
+ * optimizations in Mesa's compiler. Specifically, MR !10012
+ * had a pattern
+ *
+ * (('ior', ('ior(is_used_once)', ('flt(is_used_once)', a, c), d), ('flt', b, c)),
+ * ('ior', ('flt', ('fmin', a, b), c), d)),
+ *
+ * Since this did not mark the replacement fmin as exact, it could
+ * allow another pattern like
+ *
+ * (('~fmin', ('fmax', a, -1.0), 0.0),
+ * ('fneg', ('fsat', ('fneg', a))), '!options->lower_fsat'),
+ *
+ * This would produce a different result when `a` is NaN. The
+ * original min-of-max produces -1, but fsat produces 0. If -1 <
+ * c < 0, then the comparison will produce a different result.
+ */
+ float a = max((zero / also_zero) + (inf - also_inf), -1.0);
+ const float b = 0.0;
+ float c = gl_FragCoord.x * -0.0001 -0.0001; /* Always > -1.0 and < 0.0. */
+ bool d = gl_FragCoord.y > billion; /* Always false. */
+
+ if (((a < c) || d) || (b < c))
+ piglit_fragcolor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ piglit_fragcolor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+
+[test]
+draw rect -1 -1 2 2
+probe all rgba 0.0 1.0 0.0 1.0
diff --git a/tests/spec/glsl-1.30/execution/fs-logic-joined-comparisons-with-nan2.shader_test b/tests/spec/glsl-1.30/execution/fs-logic-joined-comparisons-with-nan2.shader_test
new file mode 100644
index 000000000..d0b642319
--- /dev/null
+++ b/tests/spec/glsl-1.30/execution/fs-logic-joined-comparisons-with-nan2.shader_test
@@ -0,0 +1,52 @@
+[require]
+GLSL >= 1.30
+
+[vertex shader passthrough]
+
+[fragment shader]
+#version 130
+
+uniform float zero = 0.0;
+uniform float also_zero = 0.0;
+uniform float billion = 1000000000.0;
+uniform float flt_max = 3.40282347E+38;
+
+out vec4 piglit_fragcolor;
+
+void main()
+{
+ float inf = flt_max * flt_max;
+ float also_inf = flt_max * billion;
+
+ /* Trying very hard to trigger a potential sequence of
+ * optimizations in Mesa's compiler. Specifically, MR !10012
+ * had a pattern
+ *
+ * (('ior', ('ior(is_used_once)', ('flt(is_used_once)', a, b), d), ('flt', a, c)),
+ * ('ior', ('flt', a, ('fmax', b, c)), d)),
+ *
+ * Since this did not mark the replacement fmin as exact, it could
+ * allow another pattern like
+ *
+ * (('~fmax', ('fmin', a, 1.0), 0.0),
+ * ('fsat', a), '!options->lower_fsat'),
+ *
+ * This would produce a different result when `c` (in the first
+ * pattern) is NaN. The original max-of-min produces 1, but fsat
+ * produces 0. If 0 < a < 1, then the comparison will produce a
+ * different result.
+ */
+ float a = gl_FragCoord.x * 0.0001 + 0.0001; /* Always < 1.0 and > 0.0. */
+ const float b = 0.0;
+ float c = min((zero / also_zero) + (inf - also_inf), 1.0);
+ bool d = gl_FragCoord.y > billion; /* Always false. */
+
+ if ((a < b || d) || (a < c))
+ piglit_fragcolor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ piglit_fragcolor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+
+[test]
+draw rect -1 -1 2 2
+probe all rgba 0.0 1.0 0.0 1.0