Summary
We have reduced a fragment shader compilation issue to a small GLSL ES 3.10 reproducer on a vivo Y52s.
Calling glCompileShader() on the shader below does not return during our tests. The application subsequently receives Android's TRIM_MEMORY_RUNNING_CRITICAL notification and becomes unusable.
The shader is compiled independently: it is not linked into a program or executed.
Removing the zero-iteration loop allows compilation to complete successfully. We suspect a driver compiler issue, potentially involving loop analysis or dynamic array indexing. We have not established whether the memory pressure is caused by a leak or excessive compiler allocations.
Environment
Device: vivo Y52s, model V2057AGPU: Mali-G57 MC3GL_VERSION:textOpenGL ES 3.2 v1.r21p0-01rel0.c11ccc92e3ee92482b99c5f086460a1fShader language: GLSL ES 3.10Application: Native Android application based on a customized Unreal Engine 4.26.1
Minimal Reproducer
#version 310 es precision mediump float; precision highp int; layout(location = 0) in highp vec4 in_TEXCOORD0; layout(location = 0) out vec4 out_Target0; void main() { highp vec2 texCoords[1]; texCoords[0] = in_TEXCOORD0.xy; uint index = 8u; for (;;) { if (index >= 1u) { break; } texCoords[int(index)] = vec2(0.0); index = index + 1u; } out_Target0 = vec4(texCoords[0], 0.0, 1.0); }
The loop should execute zero iterations: index starts at 8u, so the first condition is true and execution immediately leaves the loop. The dynamically indexed array write is therefore unreachable; no out-of-bounds access should occur during shader execution.
Reproduction Steps
With a valid OpenGL ES context current:
GLuint shader = glCreateShader(GL_FRAGMENT_SHADER); const GLchar* source = /* GLSL source above */; GLint length = /* source length in bytes */; glShaderSource(shader, 1, &source, &length); glCompileShader(shader); // Does not return during our tests.
No program linking, draw calls, or shader execution is required.
Observed BehaviorFor the minimal reproducer, our last recorded message before entering the driver was:
GLDebugShader BEGIN Resource=15 SourceCRC=7db0e5bb Bytes=469Our log immediately after glCompileShader() was not reached.
The original, larger shader showed the same behavior, followed by Android's critical memory-pressure notification. Removing only the corresponding loop from that shader allowed it to compile successfully in approximately 22 ms, with GL_COMPILE_STATUS == GL_TRUE.
A separate constant-output fragment shader also compiled successfully.
Questions
We can provide the original shader and additional device logs if useful.
Thank you for your time and help investigating this issue. We would appreciate any guidance or confirmation from the Arm team, and we are happy to provide additional logs or test potential fixes on the affected device.
At the suspected loop-expansion routine, the repetition limit is 0xFFFFFFFA (4,294,967,290), while the current counter has reached 0x72667 (468,583). The loop uses an unsigned comparison. Stack values also contain 0xFFFFFFF9, consistent with unsigned wraparound of 1 - 8. This strongly suggests an incorrect trip-count calculation for the zero-iteration loop, followed by excessive IR/control-flow cloning.