diff options
author | Ian Romanick <ian.d.romanick@intel.com> | 2018-09-12 15:44:49 -0700 |
---|---|---|
committer | Ian Romanick <ian.d.romanick@intel.com> | 2018-09-17 00:33:20 -0700 |
commit | 975fd8853a71db461e9e4e50eb592402df6bcc67 (patch) | |
tree | e073f0ae0fbb171578c7a55ff49c0938a87ac119 | |
parent | c0350279c5c1972a1ccff65b91de10ab9f4567e9 (diff) |
shaders: Reproduce a bug in the i965 backend optimizer
The optimizer recently added the ability to replace a compare with a
subtraction under certain circumstances. This can fail for integers.
For inputs a = 0x80000000, b = 4, int(0x80000000) < 4, but
int(0x80000000) - 4 overflows and results in 0x7ffffffc. That's not
less than zero, so the flags get set differently than for (a < b).
This really only affected the signed comparisons because the subtract
would always have a signed source types, so it wouldn't be seen as a
match for the compare with unsigned source types.
v2: Just require GL_EXT_shader_integer_mix. Remove stray change to
tests/spec/CMakeLists.txt. Both suggested by Ilia. Since this is no
longer a "stock" GLSL 1.30 test, move to tests/shaders/.
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Cc: Matt Turner <mattst88@gmail.com>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
4 files changed, 350 insertions, 0 deletions
diff --git a/tests/shaders/glsl-fs-absoluteDifference-int.shader_test b/tests/shaders/glsl-fs-absoluteDifference-int.shader_test new file mode 100644 index 000000000..5fd26d7ff --- /dev/null +++ b/tests/shaders/glsl-fs-absoluteDifference-int.shader_test @@ -0,0 +1,82 @@ +[require] +GL >= 3.0 +GLSL >= 1.30 +GL_EXT_shader_integer_mix + +[vertex shader passthrough] + +[fragment shader] +#extension GL_EXT_shader_integer_mix: require + +// { A, B, absoluteDifference(A, B) } +uniform ivec3 data[40]; + +out vec4 color; + +uint abs_diff(int a, int b) +{ + /* This can fail if the compiler replaces the (a < b) with the result of + * one of the subtractions. For inputs a = 0x80000000, b = 4, + * int(0x80000000) < 4, but int(0x80000000)-4 overflows and results in + * 0x7ffffffc. That's not less than zero, so the flags get set + * differently than for (a < b). + */ + return mix(uint(a - b), uint(b - a), a < b); +} + +void main() +{ + uint idx = uint(gl_FragCoord.x) % uint(data.length()); + ivec3 v = data[idx]; + + if (abs_diff(v.x, v.y) == uint(v.z)) { + color = vec4(0.0, 1.0, 0.0, 1.0); + } else { + color = vec4(1.0, 0.0, 0.0, 1.0); + } +} + +[test] +uniform ivec3 data[0] 0x80000000 0x80000000 0x00000000 +uniform ivec3 data[1] 0x80000000 0x80000001 0x00000001 +uniform ivec3 data[2] 0x80000000 0xf8000000 0x78000000 +uniform ivec3 data[3] 0x80000000 0xf8000001 0x78000001 +uniform ivec3 data[4] 0x80000000 0xff800000 0x7f800000 +uniform ivec3 data[5] 0x80000000 0xff800001 0x7f800001 +uniform ivec3 data[6] 0x80000000 0xfff80000 0x7ff80000 +uniform ivec3 data[7] 0x80000000 0xfff80001 0x7ff80001 +uniform ivec3 data[8] 0x80000000 0xffff8000 0x7fff8000 +uniform ivec3 data[9] 0x80000000 0xffff8001 0x7fff8001 +uniform ivec3 data[10] 0x80000000 0xfffff800 0x7ffff800 +uniform ivec3 data[11] 0x80000000 0xfffff801 0x7ffff801 +uniform ivec3 data[12] 0x80000000 0xffffff80 0x7fffff80 +uniform ivec3 data[13] 0x80000000 0xffffff81 0x7fffff81 +uniform ivec3 data[14] 0x80000000 0xfffffff8 0x7ffffff8 +uniform ivec3 data[15] 0x80000000 0xfffffff9 0x7ffffff9 +uniform ivec3 data[16] 0x80000000 0xfffffffa 0x7ffffffa +uniform ivec3 data[17] 0x80000000 0xfffffffb 0x7ffffffb +uniform ivec3 data[18] 0x80000000 0xfffffffc 0x7ffffffc +uniform ivec3 data[19] 0x80000000 0xfffffffd 0x7ffffffd +uniform ivec3 data[20] 0x80000000 0xfffffffe 0x7ffffffe +uniform ivec3 data[21] 0x80000000 0xffffffff 0x7fffffff +uniform ivec3 data[22] 0x80000000 0x00000000 0x80000000 +uniform ivec3 data[23] 0x80000000 0x00000001 0x80000001 +uniform ivec3 data[24] 0x80000000 0x00000002 0x80000002 +uniform ivec3 data[25] 0x80000000 0x00000003 0x80000003 +uniform ivec3 data[26] 0x80000000 0x00000004 0x80000004 +uniform ivec3 data[27] 0x80000000 0x00000005 0x80000005 +uniform ivec3 data[28] 0x80000000 0x00000006 0x80000006 +uniform ivec3 data[29] 0x80000000 0x00000007 0x80000007 +uniform ivec3 data[30] 0x80000000 0x00000008 0x80000008 +uniform ivec3 data[31] 0x80000000 0x0000007f 0x8000007f +uniform ivec3 data[32] 0x80000000 0x00000080 0x80000080 +uniform ivec3 data[33] 0x80000000 0x000007ff 0x800007ff +uniform ivec3 data[34] 0x80000000 0x00000800 0x80000800 +uniform ivec3 data[35] 0x80000000 0x00007fff 0x80007fff +uniform ivec3 data[36] 0x80000000 0x00008000 0x80008000 +uniform ivec3 data[37] 0x80000000 0x0007ffff 0x8007ffff +uniform ivec3 data[38] 0x80000000 0x00080000 0x80080000 +uniform ivec3 data[39] 0x80000000 0x007fffff 0x807fffff + +draw rect -1 -1 2 2 +probe all rgb 0.0 1.0 0.0 diff --git a/tests/shaders/glsl-fs-absoluteDifference-uint.shader_test b/tests/shaders/glsl-fs-absoluteDifference-uint.shader_test new file mode 100644 index 000000000..17a888888 --- /dev/null +++ b/tests/shaders/glsl-fs-absoluteDifference-uint.shader_test @@ -0,0 +1,82 @@ +[require] +GL >= 3.0 +GLSL >= 1.30 +GL_EXT_shader_integer_mix + +[vertex shader passthrough] + +[fragment shader] +#extension GL_EXT_shader_integer_mix: require + +// { A, B, absoluteDifference(A, B) } +uniform uvec3 data[40]; + +out vec4 color; + +uint abs_diff(uint a, uint b) +{ + /* This can fail if the compiler replaces the (a < b) with the result of + * one of the subtractions. For inputs a = 0x80000000, b = 4, + * int(0x80000000) < 4, but int(0x80000000)-4 overflows and results in + * 0x7ffffffc. That's not less than zero, so the flags get set + * differently than for (a < b). + */ + return mix(a - b, b - a, a < b); +} + +void main() +{ + uint idx = uint(gl_FragCoord.x) % uint(data.length()); + uvec3 v = data[idx]; + + if (abs_diff(v.x, v.y) == uint(v.z)) { + color = vec4(0.0, 1.0, 0.0, 1.0); + } else { + color = vec4(1.0, 0.0, 0.0, 1.0); + } +} + +[test] +uniform uvec3 data[0] 0x80000000 0x80000000 0x00000000 +uniform uvec3 data[1] 0x80000000 0x80000001 0x00000001 +uniform uvec3 data[2] 0x80000000 0xf8000000 0x78000000 +uniform uvec3 data[3] 0x80000000 0xf8000001 0x78000001 +uniform uvec3 data[4] 0x80000000 0xff800000 0x7f800000 +uniform uvec3 data[5] 0x80000000 0xff800001 0x7f800001 +uniform uvec3 data[6] 0x80000000 0xfff80000 0x7ff80000 +uniform uvec3 data[7] 0x80000000 0xfff80001 0x7ff80001 +uniform uvec3 data[8] 0x80000000 0xffff8000 0x7fff8000 +uniform uvec3 data[9] 0x80000000 0xffff8001 0x7fff8001 +uniform uvec3 data[10] 0x80000000 0xfffff800 0x7ffff800 +uniform uvec3 data[11] 0x80000000 0xfffff801 0x7ffff801 +uniform uvec3 data[12] 0x80000000 0xffffff80 0x7fffff80 +uniform uvec3 data[13] 0x80000000 0xffffff81 0x7fffff81 +uniform uvec3 data[14] 0x80000000 0xfffffff8 0x7ffffff8 +uniform uvec3 data[15] 0x80000000 0xfffffff9 0x7ffffff9 +uniform uvec3 data[16] 0x80000000 0xfffffffa 0x7ffffffa +uniform uvec3 data[17] 0x80000000 0xfffffffb 0x7ffffffb +uniform uvec3 data[18] 0x80000000 0xfffffffc 0x7ffffffc +uniform uvec3 data[19] 0x80000000 0xfffffffd 0x7ffffffd +uniform uvec3 data[20] 0x80000000 0xfffffffe 0x7ffffffe +uniform uvec3 data[21] 0x80000000 0xffffffff 0x7fffffff +uniform uvec3 data[22] 0x80000000 0x00000000 0x80000000 +uniform uvec3 data[23] 0x80000000 0x00000001 0x7fffffff +uniform uvec3 data[24] 0x80000000 0x00000002 0x7ffffffe +uniform uvec3 data[25] 0x80000000 0x00000003 0x7ffffffd +uniform uvec3 data[26] 0x80000000 0x00000004 0x7ffffffc +uniform uvec3 data[27] 0x80000000 0x00000005 0x7ffffffb +uniform uvec3 data[28] 0x80000000 0x00000006 0x7ffffffa +uniform uvec3 data[29] 0x80000000 0x00000007 0x7ffffff9 +uniform uvec3 data[30] 0x80000000 0x00000008 0x7ffffff8 +uniform uvec3 data[31] 0x80000000 0x0000007f 0x7fffff81 +uniform uvec3 data[32] 0x80000000 0x00000080 0x7fffff80 +uniform uvec3 data[33] 0x80000000 0x000007ff 0x7ffff801 +uniform uvec3 data[34] 0x80000000 0x00000800 0x7ffff800 +uniform uvec3 data[35] 0x80000000 0x00007fff 0x7fff8001 +uniform uvec3 data[36] 0x80000000 0x00008000 0x7fff8000 +uniform uvec3 data[37] 0x80000000 0x0007ffff 0x7ff80001 +uniform uvec3 data[38] 0x80000000 0x00080000 0x7ff80000 +uniform uvec3 data[39] 0x80000000 0x007fffff 0x7f800001 + +draw rect -1 -1 2 2 +probe all rgb 0.0 1.0 0.0 diff --git a/tests/shaders/glsl-vs-absoluteDifference-int.shader_test b/tests/shaders/glsl-vs-absoluteDifference-int.shader_test new file mode 100644 index 000000000..455ee16ad --- /dev/null +++ b/tests/shaders/glsl-vs-absoluteDifference-int.shader_test @@ -0,0 +1,93 @@ +[require] +GL >= 3.0 +GLSL >= 1.30 +GL_EXT_shader_integer_mix + +[vertex shader] +#extension GL_EXT_shader_integer_mix: require + +// { A, B, absoluteDifference(A, B) } +uniform ivec3 data[40]; + +in vec4 piglit_vertex; +out vec4 color; + +uint abs_diff(int a, int b) +{ + /* This can fail if the compiler replaces the (a < b) with the result of + * one of the subtractions. For inputs a = 0x80000000, b = 4, + * int(0x80000000) < 4, but int(0x80000000)-4 overflows and results in + * 0x7ffffffc. That's not less than zero, so the flags get set + * differently than for (a < b). + */ + return mix(uint(a - b), uint(b - a), a < b); +} + +void main() +{ + color = vec4(0.0, 1.0, 0.0, 1.0); + + for (int i = 0; i < data.length(); i++) { + ivec3 v = data[i]; + + if (abs_diff(v.x, v.y) != uint(v.z)) + color = vec4(1.0, 0.0, 0.0, 1.0); + } + + gl_Position = piglit_vertex; +} + + +[fragment shader] +in vec4 color; +out vec4 piglit_fragcolor; + +void main() +{ + piglit_fragcolor = color; +} + +[test] +uniform ivec3 data[0] 0x80000000 0x80000000 0x00000000 +uniform ivec3 data[1] 0x80000000 0x80000001 0x00000001 +uniform ivec3 data[2] 0x80000000 0xf8000000 0x78000000 +uniform ivec3 data[3] 0x80000000 0xf8000001 0x78000001 +uniform ivec3 data[4] 0x80000000 0xff800000 0x7f800000 +uniform ivec3 data[5] 0x80000000 0xff800001 0x7f800001 +uniform ivec3 data[6] 0x80000000 0xfff80000 0x7ff80000 +uniform ivec3 data[7] 0x80000000 0xfff80001 0x7ff80001 +uniform ivec3 data[8] 0x80000000 0xffff8000 0x7fff8000 +uniform ivec3 data[9] 0x80000000 0xffff8001 0x7fff8001 +uniform ivec3 data[10] 0x80000000 0xfffff800 0x7ffff800 +uniform ivec3 data[11] 0x80000000 0xfffff801 0x7ffff801 +uniform ivec3 data[12] 0x80000000 0xffffff80 0x7fffff80 +uniform ivec3 data[13] 0x80000000 0xffffff81 0x7fffff81 +uniform ivec3 data[14] 0x80000000 0xfffffff8 0x7ffffff8 +uniform ivec3 data[15] 0x80000000 0xfffffff9 0x7ffffff9 +uniform ivec3 data[16] 0x80000000 0xfffffffa 0x7ffffffa +uniform ivec3 data[17] 0x80000000 0xfffffffb 0x7ffffffb +uniform ivec3 data[18] 0x80000000 0xfffffffc 0x7ffffffc +uniform ivec3 data[19] 0x80000000 0xfffffffd 0x7ffffffd +uniform ivec3 data[20] 0x80000000 0xfffffffe 0x7ffffffe +uniform ivec3 data[21] 0x80000000 0xffffffff 0x7fffffff +uniform ivec3 data[22] 0x80000000 0x00000000 0x80000000 +uniform ivec3 data[23] 0x80000000 0x00000001 0x80000001 +uniform ivec3 data[24] 0x80000000 0x00000002 0x80000002 +uniform ivec3 data[25] 0x80000000 0x00000003 0x80000003 +uniform ivec3 data[26] 0x80000000 0x00000004 0x80000004 +uniform ivec3 data[27] 0x80000000 0x00000005 0x80000005 +uniform ivec3 data[28] 0x80000000 0x00000006 0x80000006 +uniform ivec3 data[29] 0x80000000 0x00000007 0x80000007 +uniform ivec3 data[30] 0x80000000 0x00000008 0x80000008 +uniform ivec3 data[31] 0x80000000 0x0000007f 0x8000007f +uniform ivec3 data[32] 0x80000000 0x00000080 0x80000080 +uniform ivec3 data[33] 0x80000000 0x000007ff 0x800007ff +uniform ivec3 data[34] 0x80000000 0x00000800 0x80000800 +uniform ivec3 data[35] 0x80000000 0x00007fff 0x80007fff +uniform ivec3 data[36] 0x80000000 0x00008000 0x80008000 +uniform ivec3 data[37] 0x80000000 0x0007ffff 0x8007ffff +uniform ivec3 data[38] 0x80000000 0x00080000 0x80080000 +uniform ivec3 data[39] 0x80000000 0x007fffff 0x807fffff + +draw rect -1 -1 2 2 +probe all rgb 0.0 1.0 0.0 diff --git a/tests/shaders/glsl-vs-absoluteDifference-uint.shader_test b/tests/shaders/glsl-vs-absoluteDifference-uint.shader_test new file mode 100644 index 000000000..03ed6fa95 --- /dev/null +++ b/tests/shaders/glsl-vs-absoluteDifference-uint.shader_test @@ -0,0 +1,93 @@ +[require] +GL >= 3.0 +GLSL >= 1.30 +GL_EXT_shader_integer_mix + +[vertex shader] +#extension GL_EXT_shader_integer_mix: require + +// { A, B, absoluteDifference(A, B) } +uniform uvec3 data[40]; + +in vec4 piglit_vertex; +out vec4 color; + +uint abs_diff(uint a, uint b) +{ + /* This can fail if the compiler replaces the (a < b) with the result of + * one of the subtractions. For inputs a = 0x80000000, b = 4, + * int(0x80000000) < 4, but int(0x80000000)-4 overflows and results in + * 0x7ffffffc. That's not less than zero, so the flags get set + * differently than for (a < b). + */ + return mix(a - b, b - a, a < b); +} + +void main() +{ + color = vec4(0.0, 1.0, 0.0, 1.0); + + for (int i = 0; i < data.length(); i++) { + uvec3 v = data[i]; + + if (abs_diff(v.x, v.y) != uint(v.z)) + color = vec4(1.0, 0.0, 0.0, 1.0); + } + + gl_Position = piglit_vertex; +} + + +[fragment shader] +in vec4 color; +out vec4 piglit_fragcolor; + +void main() +{ + piglit_fragcolor = color; +} + +[test] +uniform uvec3 data[0] 0x80000000 0x80000000 0x00000000 +uniform uvec3 data[1] 0x80000000 0x80000001 0x00000001 +uniform uvec3 data[2] 0x80000000 0xf8000000 0x78000000 +uniform uvec3 data[3] 0x80000000 0xf8000001 0x78000001 +uniform uvec3 data[4] 0x80000000 0xff800000 0x7f800000 +uniform uvec3 data[5] 0x80000000 0xff800001 0x7f800001 +uniform uvec3 data[6] 0x80000000 0xfff80000 0x7ff80000 +uniform uvec3 data[7] 0x80000000 0xfff80001 0x7ff80001 +uniform uvec3 data[8] 0x80000000 0xffff8000 0x7fff8000 +uniform uvec3 data[9] 0x80000000 0xffff8001 0x7fff8001 +uniform uvec3 data[10] 0x80000000 0xfffff800 0x7ffff800 +uniform uvec3 data[11] 0x80000000 0xfffff801 0x7ffff801 +uniform uvec3 data[12] 0x80000000 0xffffff80 0x7fffff80 +uniform uvec3 data[13] 0x80000000 0xffffff81 0x7fffff81 +uniform uvec3 data[14] 0x80000000 0xfffffff8 0x7ffffff8 +uniform uvec3 data[15] 0x80000000 0xfffffff9 0x7ffffff9 +uniform uvec3 data[16] 0x80000000 0xfffffffa 0x7ffffffa +uniform uvec3 data[17] 0x80000000 0xfffffffb 0x7ffffffb +uniform uvec3 data[18] 0x80000000 0xfffffffc 0x7ffffffc +uniform uvec3 data[19] 0x80000000 0xfffffffd 0x7ffffffd +uniform uvec3 data[20] 0x80000000 0xfffffffe 0x7ffffffe +uniform uvec3 data[21] 0x80000000 0xffffffff 0x7fffffff +uniform uvec3 data[22] 0x80000000 0x00000000 0x80000000 +uniform uvec3 data[23] 0x80000000 0x00000001 0x7fffffff +uniform uvec3 data[24] 0x80000000 0x00000002 0x7ffffffe +uniform uvec3 data[25] 0x80000000 0x00000003 0x7ffffffd +uniform uvec3 data[26] 0x80000000 0x00000004 0x7ffffffc +uniform uvec3 data[27] 0x80000000 0x00000005 0x7ffffffb +uniform uvec3 data[28] 0x80000000 0x00000006 0x7ffffffa +uniform uvec3 data[29] 0x80000000 0x00000007 0x7ffffff9 +uniform uvec3 data[30] 0x80000000 0x00000008 0x7ffffff8 +uniform uvec3 data[31] 0x80000000 0x0000007f 0x7fffff81 +uniform uvec3 data[32] 0x80000000 0x00000080 0x7fffff80 +uniform uvec3 data[33] 0x80000000 0x000007ff 0x7ffff801 +uniform uvec3 data[34] 0x80000000 0x00000800 0x7ffff800 +uniform uvec3 data[35] 0x80000000 0x00007fff 0x7fff8001 +uniform uvec3 data[36] 0x80000000 0x00008000 0x7fff8000 +uniform uvec3 data[37] 0x80000000 0x0007ffff 0x7ff80001 +uniform uvec3 data[38] 0x80000000 0x00080000 0x7ff80000 +uniform uvec3 data[39] 0x80000000 0x007fffff 0x7f800001 + +draw rect -1 -1 2 2 +probe all rgb 0.0 1.0 0.0 |