glslang/Test/precise.tesc
qining 9220dbb078 Precise and noContraction propagation
Reimplement the whole workflow to make that: precise'ness of struct
    members won't spread to other non-precise members of the same struct
    instance.

    Approach:
    1. Build the map from symbols to their defining nodes. And for each
    object node (StructIndex, DirectIndex, Symbol nodes, etc), generates an
    accesschain path. Different AST nodes that indicating a same object
    should have the same accesschain path.

    2. Along the building phase in step 1, collect the initial set of
    'precise' (AST qualifier: 'noContraction') objects' accesschain paths.

    3. Start with the initial set of 'precise' accesschain paths, use it as
    a worklist, do as the following steps until the worklist is empty:

        1) Pop an accesschain path from worklist.
        2) Get the symbol part from the accesschain path.
        3) Find the defining nodes of that symbol.
        4) For each defining node, check whether it is defining a 'precise'
        object, or its assignee has nested 'precise' object. Get the
        incremental path from assignee to its nested 'precise' object (if
        any).
        5) Traverse the right side of the defining node, obtain the
        accesschain paths of the corresponding involved 'precise' objects.
        Update the worklist with those new objects' accesschain paths.
        Label involved operations with 'noContraction'.

    In each step, whenever we find the parent object of an nested object is
    'precise' (has 'noContraction' qualifier), we let the nested object
    inherit the 'precise'ness from its parent object.
2016-05-09 10:46:40 -04:00

103 lines
2.5 KiB
GLSL

#version 450
#extension GL_EXT_tessellation_shader : require
#extension GL_EXT_gpu_shader5 : require
float minimal() {
precise float result = 5.0;
float a = 10.0;
float b = 20.0;
float c = 30.0;
float d = 40.0;
result = a * b + c * d; // c * d, a * b and rvalue1 + rvalue2 should be 'noContraction'.
return result;
}
void continuous_assignment() {
precise float result = 5.0;
int a = 10;
int b = 20;
result = a = b + 4; // b + 4 should be 'noContraction'.
}
void convert() {
precise float result;
int a = 10;
int b = 20;
b = a + b; // a + b should be 'noContraction'.
result = float(b); // convert operation should not be 'noContraction'.
}
float loop_for() {
precise float r1 = 5.0;
precise float r2 = 10.0;
int a = 10;
int b = 20;
int c = 30;
for (int i = 0; i < a; i++) {
r1 += 3.12 + b + i; // 'noContration', this make i++ also 'noContraction'
c += 1; // 'noContration'
}
a += 1; // a + 1 should not be 'noContraction'.
r2 = c; // The calculation of c should be 'noContration'.
return float(r1 + r2); // conversion should not be 'noContration'.
}
void loop_array(void) {
precise int result = 5;
int x = 22;
int y = 33;
int a0[3];
result += x + y; // x + y should be 'noContraction' also result + rvalue.
for (int i = 0; i < 3; ++i) {
// a's dereference + 2 should be 'noContraction'.
result += a0[i] + 2;
// result + 1 and 3 - rvalue should be 'noContraction'.
a0[i] = 3 - result++;
}
}
void loop_while() {
precise float result = 5.0;
int a = 10;
int b = 20;
while (result < 10) {
result += 3.12 + b; // result + 3.12 should be 'noContraction'.
}
result = a + b + 5; // b + 5 should be 'noCtraction' and also a + rvalue.
result = 11.1;
}
float fma_not_decorated() {
precise float result;
float a = 1.0;
float b = 2.0;
float c = 3.0;
b = b + c; // b + c should be decorated with 'noContraction'
result = fma(a, b, c); // fma() should not be decorated with 'noContradtion'
return result;
}
precise float precise_return_exp_func() {
float a = 1.0;
float b = 2.0;
return a + b; // the ADD operation should be 'noContraction'
}
precise float precise_return_val_func() {
float a = 1.0;
float b = 2.0;
float result = a + b; // the ADD operation should be 'noContraction'
return result;
}
float precise_func_parameter(float b, precise out float c) {
float a = 0.5;
c = a + b; // noContration
return a - b; // Not noContraction
}
void main(){}