google / google/shaderc

Overly aggressive specialization constant folding based on initializer value

Open
#1,497 0 comments 1 reaction 0 assignees View on GitHub
Dominant language
C++
Stars
2.2k
Forks
445
Avg merge
11h 6m
Merged PRs (30d)
6

Description

When compiling some GLSL code with specialisation constants, constant folding seems to be performed based on the initializer value of the specialisation constants, despite the fact that each specialisation constant can then be reassigned. This can result in overly-aggressive constant folding that produces invalid bytecode.

Example GLSL:
```glsl
#version 450

layout(constant_id = 0) const int FIRST_CONSTANT = 2048;
layout(constant_id = 1) const int SECOND_CONSTANT = FIRST_CONSTANT;

void main() {}
```

Resulting bytecode: (relevant part)
```
OpName %FIRST_CONSTANT "FIRST_CONSTANT"
OpName %FIRST_CONSTANT "SECOND_CONSTANT"
OpDecorate %FIRST_CONSTANT SpecId 0
OpDecorate %FIRST_CONSTANT SpecId 1
```

As you can see, the instances of `%SECOND_CONSTANT` have been replaced with `%FIRST_CONSTANT` as they are assumed to have the same value. However, this results in `%FIRST_CONSTANT` having 2 `SpecId`s, which is invalid bytecode.

Rewriting the initializer from `SECOND_CONSTANT = FIRST_CONSTANT` to `SECOND_CONSTANT = 2048` solves the issue resulting in the following bytecode:

```
OpName %FIRST_CONSTANT "FIRST_CONSTANT"
OpName %SECOND_CONSTANT "SECOND_CONSTANT"
OpDecorate %FIRST_CONSTANT SpecId 0
OpDecorate %SECOND_CONSTANT SpecId 1
```

The correct behaviour in this case would be to not perform constant folding on specialization constants based on the initializer value, as that might be changed later, at pipeline-creation time.

glslc version:
shaderc v2023.8 2024-01-03spirv-tools v2025.2 2025-04-22glslang 3362e24c42ab5bf7ad32c0fec64b0a0ddeb2fda1
Target: SPIR-V 1.0

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.