KhronosGroup / KhronosGroup/glslang

Lack of rounding of lower precision constants

Open
#4,241 4 comments 0 reactions 0 assignees View on GitHub
bug GLSL/ESSL
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.