Skip to content

Overly aggressive specialization constant folding based on initializer value #1497

@ZtereoHYPE

Description

@ZtereoHYPE

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:

#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 SpecIds, 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 3362e24
Target: SPIR-V 1.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions