If-statement body is executed for false condition
System information
- OS: LFS
- GPU: 00:02.0 Display controller: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor Integrated Graphics Controller (rev 06)
- Kernel version: 4.14.157 x86_64
- Mesa version: 20.2.0-devel (git-78615dcc)
Also reproduces on Ubuntu 19.10 (with stock Mesa 19.2.8, Linux 5.3.0-45-generic x86_64, on Intel UHD Graphics 620).
Setting LIBGL_ALWAYS_SOFTWARE=1
environment variable doesn't affect reproducibility.
Describe the issue
In the attached test C++ program (test.tar.xz), a GLSL program is constructed from 1 vertex shader and 2 fragment shaders. Then it's fed with 4 vertices of a square with coordinates x,y=±1. Here's how the shaders look:
- Vertex shader
#version 330
in vec3 vertex;
out vec3 position;
void main()
{
position=vertex;
gl_Position=vec4(position,1);
}
- Fragment shader 1
#version 330
vec4 calc(float x);
in vec3 position;
out vec4 color;
void main()
{
color=calc(position.x);
}
- Fragment shader 2
#version 330
vec4 work(float x)
{
if(x<-1e4) x=-183; // comment this out to see the correct output
return vec4(x);
}
vec4 helper3(float x)
{
return work(x);
}
vec4 helper2(float x)
{
return helper3(x);
}
vec4 helper1(float x)
{
return helper2(x);
}
vec4 calc(float x)
{
return helper1(x);
}
If you comment out the if
statement in the work()
function of fragment shader 2, the program will work as expected, outputting interpolated x-values of the input vertices:
-0.964286
-0.892857
-0.821429
-0.75
-0.678571
-0.607143
-0.535714
-0.464286
-0.392857
-0.321429
-0.25
-0.178571
-0.107143
-0.0357143
0.0357144
0.107143
0.178571
0.25
0.321429
0.392857
0.464286
0.535714
0.607143
0.678571
0.75
0.821429
0.892857
0.964286
If you don't comment this line, instead leaving it as is, it'll unconditionally execute the body of the if
statement, resulting in the output of all--183
.
If you replace the -1e4
value with any other like e.g. -1e34
, which a priori can't be greater than position.x
, the problem is still visible.
If you inline any of the helper functions, the symptom goes away. If you merge the two fragment shaders, moving all the functions from shader 2 into shader 1, the symptom also goes away.