Skip to content

Commit

Permalink
Out-of-range floats should overflow/underflow to infinity/0.0
Browse files Browse the repository at this point in the history
        glslang representing literal constants with double precision, so 1.0e40 and 1.0e-50 are normal values.

        Shader1:
        precision highp float;
        out vec4 my_FragColor;
        void main()
        {
        // Out-of-range floats should overflow to infinity
        // GLSL ES 3.00.6 section 4.1.4 Floats:
        // "If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity"
        float correct = isinf(1.0e40) ? 1.0 : 0.0;
        my_FragColor = vec4(0.0, correct, 0.0, 1.0);
        }
        The expected ouput result of this test is vec4(0.0, 1.0, 0.0, 1.0),
        but it's vec4(0.0,0.0,0.0,1.0).Because the return value of isInf is
        false.

        precision highp float;
        out vec4 my_FragColor;
        void main()
        {
        // GLSL ES 3.00.6 section 4.1.4 Floats:
        // "A value with a magnitude too small to be represented as a mantissa and exponent is converted to zero."
        // 1.0e-50 is small enough that it can't even be stored as subnormal.
        float correct = (1.0e-50 == 0.0) ? 1.0 : 0.0;
        my_FragColor = vec4(0.0, correct, 0.0, 1.0);
        }
        The expected ouput result of this test is vec4(0.0, 1.0, 0.0, 1.0),
        but it's vec4(0.0,0.0,0.0,1.0).

        For f32 and f16 type, when the literal constant out of range of the f32
        and f16 number, the value should overflow or underflow to inf or zero.

            glcts test item
        KHR-GLES3.number_parsing.float_out_of_range_as_infinity
  • Loading branch information
jimihem authored and arcady-lunarg committed Nov 17, 2023
1 parent 845e5d5 commit 854db99
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 0 deletions.
28 changes: 28 additions & 0 deletions Test/baseResults/overflow_underflow_toinf_0.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
overflow_underflow_toinf_0.frag
Shader version: 320
0:? Sequence
0:4 Function Definition: main( ( global void)
0:4 Function Parameters:
0:9 Sequence
0:9 Sequence
0:9 move second child to first child ( temp highp float)
0:9 'correct' ( temp highp float)
0:9 Constant:
0:9 1.000000
0:10 Sequence
0:10 move second child to first child ( temp highp float)
0:10 'correct1' ( temp highp float)
0:10 Constant:
0:10 1.000000
0:11 move second child to first child ( temp highp 4-component vector of float)
0:11 'my_FragColor' ( out highp 4-component vector of float)
0:11 Construct vec4 ( temp highp 4-component vector of float)
0:11 Constant:
0:11 0.000000
0:11 'correct' ( temp highp float)
0:11 'correct1' ( temp highp float)
0:11 Constant:
0:11 1.000000
0:? Linker Objects
0:? 'my_FragColor' ( out highp 4-component vector of float)

12 changes: 12 additions & 0 deletions Test/overflow_underflow_toinf_0.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#version 320 es
precision highp float;
out vec4 my_FragColor;
void main()
{
// GLSL ES 3.00.6 section 4.1.4 Floats:
// "A value with a magnitude too small to be represented as a mantissa and exponent is converted to zero."
// 1.0e-50 is small enough that it can't even be stored as subnormal.
float correct = (1.0e-50 == 0.0) ? 1.0 : 0.0;
float correct1 = isinf(1.0e40) ? 1.0 : 0.0;
my_FragColor = vec4(0.0, correct, correct1, 1.0);
}
2 changes: 2 additions & 0 deletions Test/runtests
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,8 @@ run --enhanced-msgs -V --target-env vulkan1.2 --amb --aml enhanced.7.vert enhanc
diff -b $BASEDIR/enhanced.7.link.out $TARGETDIR/enhanced.7.link.out || HASERROR=1
run --enhanced-msgs -V --target-env vulkan1.2 --amb --aml spv.textureError.frag > $TARGETDIR/spv.textureError.frag.out
diff -b $BASEDIR/spv.textureError.frag.out $TARGETDIR/spv.textureError.frag.out || HASERROR=1
run -i overflow_underflow_toinf_0.frag > $TARGETDIR/overflow_underflow_toinf_0.out
diff -b $BASEDIR/overflow_underflow_toinf_0.out $TARGETDIR/overflow_underflow_toinf_0.out || HASERROR=1

#
# Final checking
Expand Down
12 changes: 12 additions & 0 deletions glslang/MachineIndependent/Intermediate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2590,6 +2590,18 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseT
{
assert(baseType == EbtFloat || baseType == EbtDouble || baseType == EbtFloat16);

if (isEsProfile() && (baseType == EbtFloat || baseType == EbtFloat16)) {
int exponent = 0;
frexp(d, &exponent);
int minExp = baseType == EbtFloat ? -126 : -14;
int maxExp = baseType == EbtFloat ? 127 : 15;
if (exponent > maxExp) { //overflow, d = inf
d = std::numeric_limits<double>::infinity();
} else if (exponent < minExp) { //underflow, d = 0.0;
d = 0.0;
}
}

TConstUnionArray unionArray(1);
unionArray[0].setDConst(d);

Expand Down

0 comments on commit 854db99

Please sign in to comment.