KhronosGroup / KhronosGroup/glslang
Lack of rounding of lower precision constants
- Dominant language
- C++
- Stars
- 3.6k
- Forks
- 989
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 31
Description
Constant values have a nonobvious behavior where they are not rounded until the SPIR-V OpConstant is emitted. The ConstantUnion stores them in double precision regardless of declared type. This means bits that should have been rounded away can contribute to calculations involving those constants. For example:
```
#version 450
#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require
const float16_t c0 = 1.000000001hf; // would be rounded to 1.0 in fp16 or fp32
const float c1 = 1000000*(c0 - 1.0f);
void main() {
}
```
generates:
```
%half_0x1p_0 = OpConstant %half 0x1p+0
%float_0_00100000005 = OpConstant %float 0.00100000005
```
(see https://godbolt.org/z/x9vEEzeq1).
A developer would reasonably expect c0 to be rounded to exactly 1, and then for c1 to compute a value of zero.
I don't know if we should "fix" this (seems a bit risky?), or maybe add a warning somewhere. Or maybe try to document the behavior?
Contributor guide
Research direction
Start by tracing ConstantUnion through constant evaluation and the point where the SPIR-V OpConstant is emitted. Reproduce the float16 example and compare the generated constants; the issue needs a decided outcome—rounding, a warning, or documentation—before completion can be verified.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 42/100