[Piglit] [PATCH] add GLSL inlining/unroll limit tests, currently failing

Luca Barbieri luca at luca-barbieri.com
Sun Sep 5 19:56:05 PDT 2010


The current GLSL compiler inlines everything indiscriminately,
and unrolls all loops that have a small iteration count.

This is a bad idea, because it can lead to exponential growth of
the code, as these test cases illustrate.

On a naive implementation (like current Mesa) these tests will
attempt to allocate more than 2^64 bytes of RAM, ensuring failure.

A smart implementation will instead generate actual calls/loops, and the
test passes, since the branch protecting the functions/loops is not taken.

Currently they aren't added to any profile since they obviously cause
piglit to hang until memory is exhausted, possibly causing lots of
swap thrashing.
---
 tests/shaders/glsl-fs-inline-explosion.shader_test |  415 ++++++++++++++++++++
 tests/shaders/glsl-fs-unroll-explosion.shader_test |   45 +++
 tests/shaders/glsl-vs-inline-explosion.shader_test |  413 +++++++++++++++++++
 tests/shaders/glsl-vs-unroll-explosion.shader_test |   44 ++
 4 files changed, 917 insertions(+), 0 deletions(-)
 create mode 100644 tests/shaders/glsl-fs-inline-explosion.shader_test
 create mode 100644 tests/shaders/glsl-fs-unroll-explosion.shader_test
 create mode 100644 tests/shaders/glsl-vs-inline-explosion.shader_test
 create mode 100644 tests/shaders/glsl-vs-unroll-explosion.shader_test

diff --git a/tests/shaders/glsl-fs-inline-explosion.shader_test b/tests/shaders/glsl-fs-inline-explosion.shader_test
new file mode 100644
index 0000000..227012d
--- /dev/null
+++ b/tests/shaders/glsl-fs-inline-explosion.shader_test
@@ -0,0 +1,415 @@
+// if you inline all functions indiscriminately, you won't pass this
+[require]
+GL >= 2.0
+GLSL >= 1.10
+
+[vertex shader]
+void main()
+{
+	gl_Position = gl_Vertex;
+	gl_TexCoord[0] = gl_Position;
+}
+
+[fragment shader]
+void f64()
+{
+// use something that cannot be optimized away
+	gl_FragColor = exp(gl_FragColor);
+}
+
+
+void f63()
+{
+	f64();
+	f64();
+}
+
+void f62()
+{
+	f63();
+	f63();
+}
+
+void f61()
+{
+	f62();
+	f62();
+}
+
+void f60()
+{
+	f61();
+	f61();
+}
+
+void f59()
+{
+	f60();
+	f60();
+}
+
+void f58()
+{
+	f59();
+	f59();
+}
+
+void f57()
+{
+	f58();
+	f58();
+}
+
+void f56()
+{
+	f57();
+	f57();
+}
+
+void f55()
+{
+	f56();
+	f56();
+}
+
+void f54()
+{
+	f55();
+	f55();
+}
+
+void f53()
+{
+	f54();
+	f54();
+}
+
+void f52()
+{
+	f53();
+	f53();
+}
+
+void f51()
+{
+	f52();
+	f52();
+}
+
+void f50()
+{
+	f51();
+	f51();
+}
+
+void f49()
+{
+	f50();
+	f50();
+}
+
+void f48()
+{
+	f49();
+	f49();
+}
+
+void f47()
+{
+	f48();
+	f48();
+}
+
+void f46()
+{
+	f47();
+	f47();
+}
+
+void f45()
+{
+	f46();
+	f46();
+}
+
+void f44()
+{
+	f45();
+	f45();
+}
+
+void f43()
+{
+	f44();
+	f44();
+}
+
+void f42()
+{
+	f43();
+	f43();
+}
+
+void f41()
+{
+	f42();
+	f42();
+}
+
+void f40()
+{
+	f41();
+	f41();
+}
+
+void f39()
+{
+	f40();
+	f40();
+}
+
+void f38()
+{
+	f39();
+	f39();
+}
+
+void f37()
+{
+	f38();
+	f38();
+}
+
+void f36()
+{
+	f37();
+	f37();
+}
+
+void f35()
+{
+	f36();
+	f36();
+}
+
+void f34()
+{
+	f35();
+	f35();
+}
+
+void f33()
+{
+	f34();
+	f34();
+}
+
+void f32()
+{
+	f33();
+	f33();
+}
+
+void f31()
+{
+	f32();
+	f32();
+}
+
+void f30()
+{
+	f31();
+	f31();
+}
+
+void f29()
+{
+	f30();
+	f30();
+}
+
+void f28()
+{
+	f29();
+	f29();
+}
+
+void f27()
+{
+	f28();
+	f28();
+}
+
+void f26()
+{
+	f27();
+	f27();
+}
+
+void f25()
+{
+	f26();
+	f26();
+}
+
+void f24()
+{
+	f25();
+	f25();
+}
+
+void f23()
+{
+	f24();
+	f24();
+}
+
+void f22()
+{
+	f23();
+	f23();
+}
+
+void f21()
+{
+	f22();
+	f22();
+}
+
+void f20()
+{
+	f21();
+	f21();
+}
+
+void f19()
+{
+	f20();
+	f20();
+}
+
+void f18()
+{
+	f19();
+	f19();
+}
+
+void f17()
+{
+	f18();
+	f18();
+}
+
+void f16()
+{
+	f17();
+	f17();
+}
+
+void f15()
+{
+	f16();
+	f16();
+}
+
+void f14()
+{
+	f15();
+	f15();
+}
+
+void f13()
+{
+	f14();
+	f14();
+}
+
+void f12()
+{
+	f13();
+	f13();
+}
+
+void f11()
+{
+	f12();
+	f12();
+}
+
+void f10()
+{
+	f11();
+	f11();
+}
+
+void f9()
+{
+	f10();
+	f10();
+}
+
+void f8()
+{
+	f9();
+	f9();
+}
+
+void f7()
+{
+	f8();
+	f8();
+}
+
+void f6()
+{
+	f7();
+	f7();
+}
+
+void f5()
+{
+	f6();
+	f6();
+}
+
+void f4()
+{
+	f5();
+	f5();
+}
+
+void f3()
+{
+	f4();
+	f4();
+}
+
+void f2()
+{
+	f3();
+	f3();
+}
+
+void f1()
+{
+	f2();
+	f2();
+}
+
+void f0()
+{
+	f1();
+	f1();
+}
+
+void main()
+{
+	gl_FragColor = vec4(0.1, 0.2, 0.3, 0.4);
+	if(gl_TexCoord[0].x > 2.0) // this branch is never taken, but the compiler doesn't know this
+		f0();
+}
+
+[test]
+draw rect -1 -1 2 2
+probe all rgba 0.1 0.2 0.3 0.4
+
diff --git a/tests/shaders/glsl-fs-unroll-explosion.shader_test b/tests/shaders/glsl-fs-unroll-explosion.shader_test
new file mode 100644
index 0000000..415bda6
--- /dev/null
+++ b/tests/shaders/glsl-fs-unroll-explosion.shader_test
@@ -0,0 +1,45 @@
+// if you unroll all loops with a few iterations, you won't pass this
+[require]
+GL >= 2.0
+GLSL >= 1.10
+
+[vertex shader]
+void main()
+{
+	gl_Position = gl_Vertex;
+	gl_TexCoord[0] = gl_Position;
+}
+
+[fragment shader]
+
+void main()
+{
+	gl_FragColor = vec4(0.1, 0.2, 0.3, 0.4);
+	if(gl_TexCoord[0].x > 2.0) // this branch is never taken, but the compiler doesn't know this
+	{
+		for(int i0 = 0; i0 < 16; ++i0)
+		for(int i1 = 0; i1 < 16; ++i1)
+		for(int i2 = 0; i2 < 16; ++i2)
+		for(int i3 = 0; i3 < 16; ++i3)
+		for(int i4 = 0; i4 < 16; ++i4)
+		for(int i5 = 0; i5 < 16; ++i5)
+		for(int i6 = 0; i6 < 16; ++i6)
+		for(int i7 = 0; i7 < 16; ++i7)
+		for(int i8 = 0; i8 < 16; ++i8)
+		for(int i9 = 0; i9 < 16; ++i9)
+		for(int i10 = 0; i10 < 16; ++i10)
+		for(int i11 = 0; i11 < 16; ++i11)
+		for(int i12 = 0; i12 < 16; ++i12)
+		for(int i13 = 0; i13 < 16; ++i13)
+		for(int i14 = 0; i14 < 16; ++i14)
+		for(int i15 = 0; i15 < 16; ++i15)
+		{
+			gl_FragColor = exp(gl_FragColor);
+		}
+	}
+}
+
+[test]
+draw rect -1 -1 2 2
+probe all rgba 0.1 0.2 0.3 0.4
+
diff --git a/tests/shaders/glsl-vs-inline-explosion.shader_test b/tests/shaders/glsl-vs-inline-explosion.shader_test
new file mode 100644
index 0000000..27593ae
--- /dev/null
+++ b/tests/shaders/glsl-vs-inline-explosion.shader_test
@@ -0,0 +1,413 @@
+// if you inline all functions indiscriminately, you won't pass this
+[require]
+GL >= 2.0
+GLSL >= 1.10
+
+[vertex shader]
+void f64()
+{
+// use something that cannot be optimized away
+	gl_TexCoord[0] = exp(gl_TexCoord[0]);
+}
+
+void f63()
+{
+	f64();
+	f64();
+}
+
+void f62()
+{
+	f63();
+	f63();
+}
+
+void f61()
+{
+	f62();
+	f62();
+}
+
+void f60()
+{
+	f61();
+	f61();
+}
+
+void f59()
+{
+	f60();
+	f60();
+}
+
+void f58()
+{
+	f59();
+	f59();
+}
+
+void f57()
+{
+	f58();
+	f58();
+}
+
+void f56()
+{
+	f57();
+	f57();
+}
+
+void f55()
+{
+	f56();
+	f56();
+}
+
+void f54()
+{
+	f55();
+	f55();
+}
+
+void f53()
+{
+	f54();
+	f54();
+}
+
+void f52()
+{
+	f53();
+	f53();
+}
+
+void f51()
+{
+	f52();
+	f52();
+}
+
+void f50()
+{
+	f51();
+	f51();
+}
+
+void f49()
+{
+	f50();
+	f50();
+}
+
+void f48()
+{
+	f49();
+	f49();
+}
+
+void f47()
+{
+	f48();
+	f48();
+}
+
+void f46()
+{
+	f47();
+	f47();
+}
+
+void f45()
+{
+	f46();
+	f46();
+}
+
+void f44()
+{
+	f45();
+	f45();
+}
+
+void f43()
+{
+	f44();
+	f44();
+}
+
+void f42()
+{
+	f43();
+	f43();
+}
+
+void f41()
+{
+	f42();
+	f42();
+}
+
+void f40()
+{
+	f41();
+	f41();
+}
+
+void f39()
+{
+	f40();
+	f40();
+}
+
+void f38()
+{
+	f39();
+	f39();
+}
+
+void f37()
+{
+	f38();
+	f38();
+}
+
+void f36()
+{
+	f37();
+	f37();
+}
+
+void f35()
+{
+	f36();
+	f36();
+}
+
+void f34()
+{
+	f35();
+	f35();
+}
+
+void f33()
+{
+	f34();
+	f34();
+}
+
+void f32()
+{
+	f33();
+	f33();
+}
+
+void f31()
+{
+	f32();
+	f32();
+}
+
+void f30()
+{
+	f31();
+	f31();
+}
+
+void f29()
+{
+	f30();
+	f30();
+}
+
+void f28()
+{
+	f29();
+	f29();
+}
+
+void f27()
+{
+	f28();
+	f28();
+}
+
+void f26()
+{
+	f27();
+	f27();
+}
+
+void f25()
+{
+	f26();
+	f26();
+}
+
+void f24()
+{
+	f25();
+	f25();
+}
+
+void f23()
+{
+	f24();
+	f24();
+}
+
+void f22()
+{
+	f23();
+	f23();
+}
+
+void f21()
+{
+	f22();
+	f22();
+}
+
+void f20()
+{
+	f21();
+	f21();
+}
+
+void f19()
+{
+	f20();
+	f20();
+}
+
+void f18()
+{
+	f19();
+	f19();
+}
+
+void f17()
+{
+	f18();
+	f18();
+}
+
+void f16()
+{
+	f17();
+	f17();
+}
+
+void f15()
+{
+	f16();
+	f16();
+}
+
+void f14()
+{
+	f15();
+	f15();
+}
+
+void f13()
+{
+	f14();
+	f14();
+}
+
+void f12()
+{
+	f13();
+	f13();
+}
+
+void f11()
+{
+	f12();
+	f12();
+}
+
+void f10()
+{
+	f11();
+	f11();
+}
+
+void f9()
+{
+	f10();
+	f10();
+}
+
+void f8()
+{
+	f9();
+	f9();
+}
+
+void f7()
+{
+	f8();
+	f8();
+}
+
+void f6()
+{
+	f7();
+	f7();
+}
+
+void f5()
+{
+	f6();
+	f6();
+}
+
+void f4()
+{
+	f5();
+	f5();
+}
+
+void f3()
+{
+	f4();
+	f4();
+}
+
+void f2()
+{
+	f3();
+	f3();
+}
+
+void f1()
+{
+	f2();
+	f2();
+}
+
+void f0()
+{
+	f1();
+	f1();
+}
+
+void main()
+{
+	gl_TexCoord[0] = vec4(0.1, 0.2, 0.3, 0.4);
+	if(gl_Vertex.x > 2.0) // this branch is never taken, but the compiler doesn't know this
+		f0();
+	gl_Position = gl_Vertex;
+}
+[fragment shader]
+void main()
+{
+	gl_FragColor = gl_TexCoord[0];
+}
+
+[test]
+draw rect -1 -1 2 2
+probe all rgba 0.1 0.2 0.3 0.4
+
diff --git a/tests/shaders/glsl-vs-unroll-explosion.shader_test b/tests/shaders/glsl-vs-unroll-explosion.shader_test
new file mode 100644
index 0000000..ef07dfa
--- /dev/null
+++ b/tests/shaders/glsl-vs-unroll-explosion.shader_test
@@ -0,0 +1,44 @@
+// if you inline all functions indiscriminately, you won't pass this
+[require]
+GL >= 2.0
+GLSL >= 1.10
+
+[vertex shader]
+
+void main()
+{
+	gl_TexCoord[0] = vec4(0.1, 0.2, 0.3, 0.4);
+	if(gl_Vertex.x > 2.0) // this branch is never taken, but the compiler doesn't know this
+	{
+		for(int i0 = 0; i0 < 16; ++i0)
+		for(int i1 = 0; i1 < 16; ++i1)
+		for(int i2 = 0; i2 < 16; ++i2)
+		for(int i3 = 0; i3 < 16; ++i3)
+		for(int i4 = 0; i4 < 16; ++i4)
+		for(int i5 = 0; i5 < 16; ++i5)
+		for(int i6 = 0; i6 < 16; ++i6)
+		for(int i7 = 0; i7 < 16; ++i7)
+		for(int i8 = 0; i8 < 16; ++i8)
+		for(int i9 = 0; i9 < 16; ++i9)
+		for(int i10 = 0; i10 < 16; ++i10)
+		for(int i11 = 0; i11 < 16; ++i11)
+		for(int i12 = 0; i12 < 16; ++i12)
+		for(int i13 = 0; i13 < 16; ++i13)
+		for(int i14 = 0; i14 < 16; ++i14)
+		for(int i15 = 0; i15 < 16; ++i15)
+		{
+			gl_TexCoord[0] = exp(gl_TexCoord[0]);
+		}
+	}
+	gl_Position = gl_Vertex;
+}
+[fragment shader]
+void main()
+{
+	gl_FragColor = gl_TexCoord[0];
+}
+
+[test]
+draw rect -1 -1 2 2
+probe all rgba 0.1 0.2 0.3 0.4
+
-- 
1.7.0.4



More information about the Piglit mailing list