mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 05:08:08 +02:00
mesa/st/tests: Add tests for improved tracking of temporaries
Additional tests are added that check the tracking of access to temporaries in if-else branches. Reviewed-by: Brian Paul <brianp@vmware.com> Signed-off-by: Gert Wollny <gw.fossdev@gmail.com>
This commit is contained in:
parent
807e2539e5
commit
517e34c62f
1 changed files with 486 additions and 7 deletions
|
|
@ -164,7 +164,7 @@ TEST_F(LifetimeEvaluatorExactTest, MoveInIfInNestedLoop)
|
|||
* - value must survive from first write to last read in loop
|
||||
* for now we only check that the minimum life time is correct.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorAtLeastTest, WriteInIfAndElseInLoop)
|
||||
TEST_F(LifetimeEvaluatorExactTest, WriteInIfAndElseInLoop)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
|
|
@ -206,6 +206,137 @@ TEST_F(LifetimeEvaluatorExactTest, WriteInIfAndElseReadInElseInLoop)
|
|||
run (code, temp_lt_expect({{-1,-1}, {0,9}, {1,9}, {7,10}}));
|
||||
}
|
||||
|
||||
|
||||
/* Test that a write in ELSE path only in loop is properly tracked:
|
||||
* In loop if/else value written in else path and read outside
|
||||
* - value must survive the whole loop.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorExactTest, WriteInElseReadInLoop)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {1}, {}},
|
||||
{ TGSI_OPCODE_UADD, {2}, {1,in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE },
|
||||
{ TGSI_OPCODE_ADD, {3}, {1,2}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_UADD, {1}, {3,in1}, {}},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_MOV, {out0}, {1}, {}},
|
||||
{ TGSI_OPCODE_END}
|
||||
};
|
||||
run (code, temp_lt_expect({{-1,-1}, {0,9}, {1,8}, {1,8}}));
|
||||
}
|
||||
|
||||
/* Test that tracking a second write in an ELSE path is not attributed
|
||||
* to the IF path: In loop if/else value written in else path twice and
|
||||
* read outside - value must survive the whole loop
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorExactTest, WriteInElseTwiceReadInLoop)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {1}, {}},
|
||||
{ TGSI_OPCODE_UADD, {2}, {1,in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE },
|
||||
{ TGSI_OPCODE_ADD, {3}, {1,2}, {}},
|
||||
{ TGSI_OPCODE_ADD, {3}, {1,3}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_UADD, {1}, {3,in1}, {}},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_MOV, {out0}, {1}, {}},
|
||||
{ TGSI_OPCODE_END}
|
||||
};
|
||||
run (code, temp_lt_expect({{-1,-1}, {0,10}, {1,9}, {1,9}}));
|
||||
}
|
||||
|
||||
/* Test that the IF and ELSE scopes from different IF/ELSE pairs are not
|
||||
* merged: In loop if/else value written in if, and then in different else path
|
||||
* and read outside - value must survive the whole loop
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorExactTest, WriteInOneIfandInAnotherElseInLoop)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {1}, {}},
|
||||
{ TGSI_OPCODE_UADD, {2}, {1,in0}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_IF, {}, {1}, {}},
|
||||
{ TGSI_OPCODE_ELSE },
|
||||
{ TGSI_OPCODE_ADD, {2}, {1,1}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_UADD, {1}, {2,in1}, {}},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_MOV, {out0}, {1}, {}},
|
||||
{ TGSI_OPCODE_END}
|
||||
};
|
||||
run (code, temp_lt_expect({{-1,-1}, {0,11}, {1,10}}));
|
||||
}
|
||||
|
||||
/* Test that with a new loop the resolution of the IF/ELSE write conditionality
|
||||
* is restarted: In first loop value is written in both if and else, in second
|
||||
* loop value is written only in if - must survive the second loop.
|
||||
* However, the tracking is currently not able to restrict the lifetime
|
||||
* in the first loop, hence the "AtLeast" test.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorAtLeastTest, UnconditionalInFirstLoopConditionalInSecond)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {1}, {}},
|
||||
{ TGSI_OPCODE_UADD, {2}, {1,in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE },
|
||||
{ TGSI_OPCODE_UADD, {2}, {1,in1}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {1}, {}},
|
||||
{ TGSI_OPCODE_ADD, {2}, {in0,1}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_UADD, {1}, {2,in1}, {}},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_MOV, {out0}, {1}, {}},
|
||||
{ TGSI_OPCODE_END}
|
||||
};
|
||||
run (code, temp_lt_expect({{-1,-1}, {0,14}, {3,13}}));
|
||||
}
|
||||
|
||||
/* Test that with a new loop the resolution of the IF/ELSE write conditionality
|
||||
* is restarted, and also takes care of write before read in else scope:
|
||||
* In first loop value is written in both if and else, in second loop value is
|
||||
* also written in both, but first read in if - must survive the second loop.
|
||||
* However, the tracking is currently not able to restrict the lifetime
|
||||
* in the first loop, hence the "AtLeast" test.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorAtLeastTest, UnconditionalInFirstLoopConditionalInSecond2)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {1}, {}},
|
||||
{ TGSI_OPCODE_UADD, {2}, {1,in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE },
|
||||
{ TGSI_OPCODE_UADD, {2}, {1,in1}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {in1}, {}},
|
||||
{ TGSI_OPCODE_ADD, {2}, {2,1}, {}},
|
||||
{ TGSI_OPCODE_ELSE },
|
||||
{ TGSI_OPCODE_MOV, {2}, {1}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_UADD, {1}, {2,in1}, {}},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_MOV, {out0}, {1}, {}},
|
||||
{ TGSI_OPCODE_END}
|
||||
};
|
||||
run (code, temp_lt_expect({{-1,-1}, {0,16}, {3,15}}));
|
||||
}
|
||||
|
||||
/* In loop if/else read in one path before written in the same loop
|
||||
* - value must survive the whole loop
|
||||
*/
|
||||
|
|
@ -262,12 +393,12 @@ TEST_F(LifetimeEvaluatorExactTest, ReadInLoopBeforeWriteAndLifeToTheEnd)
|
|||
run (code, temp_lt_expect({{-1,-1}, {0,4}}));
|
||||
}
|
||||
|
||||
|
||||
/* Write in nested ifs in loop, for now we do test whether the
|
||||
* life time is at least what is required, but we know that the
|
||||
* implementation doesn't do a full check and sets larger boundaries
|
||||
/* Test whether nesting IF/ELSE pairs within a loop is resolved:
|
||||
* Write in all conditional branches if the inner nesting level and
|
||||
* read after the outer IF/ELSE pair is closed. The lifetime doesn't have
|
||||
* to be extended to the full loop.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorAtLeastTest, NestedIfInLoopAlwaysWriteButNotPropagated)
|
||||
TEST_F(LifetimeEvaluatorExactTest, NestedIfInLoopAlwaysWriteButNotPropagated)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
|
|
@ -291,7 +422,178 @@ TEST_F(LifetimeEvaluatorAtLeastTest, NestedIfInLoopAlwaysWriteButNotPropagated)
|
|||
run (code, temp_lt_expect({{-1,-1}, {3,14}}));
|
||||
}
|
||||
|
||||
/* The value is written in a loop and in a nested if, but
|
||||
/* Test that nested chaining of IF/ELSE scopes is resolved:
|
||||
* Write in each IF branch, and open another IF/ELSE scope pair in the ELSE
|
||||
* branch. At the last nesting level, the temporary is also written in the
|
||||
* ELSE branch, hence the full constrict results in an unconditional write.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorExactTest, DeeplyNestedIfElseInLoopResolved)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ADD, {2}, {1, in1}, {}},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_MOV, {out0}, {2}, {}},
|
||||
{ TGSI_OPCODE_END}
|
||||
};
|
||||
run (code, temp_lt_expect({{-1,-1}, {2,18}, {18, 20}}));
|
||||
}
|
||||
|
||||
/* The complementary case of the above: Open deeply nested IF/ELSE clauses
|
||||
* and only at the deepest nesting level the temporary is written in the IF
|
||||
* branch, but for all ELSE scopes the value is also written. Like above, when
|
||||
* the full construct has been executed, the temporary has been written
|
||||
* unconditionally.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorExactTest, DeeplyNestedIfElseInLoopResolved2)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ADD, {2}, {1, in1}, {}},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_MOV, {out0}, {2}, {}},
|
||||
{ TGSI_OPCODE_END}
|
||||
};
|
||||
run (code, temp_lt_expect({{-1,-1}, {5,18}, {18, 20}}));
|
||||
}
|
||||
|
||||
/* Test that a write in an IF scope within IF scope where the temporary already
|
||||
* can be ignored.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorExactTest, NestedIfElseInLoopResolvedInOuterScope)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ADD, {2}, {1, in1}, {}},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_MOV, {out0}, {2}, {}},
|
||||
{ TGSI_OPCODE_END}
|
||||
};
|
||||
run (code, temp_lt_expect({{-1,-1}, {2,9}, {9, 11}}));
|
||||
}
|
||||
|
||||
/* Here the read before write in the nested if is of no consequence to the
|
||||
* life time because the variable was already written in the enclosing if-branch.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorExactTest, NestedIfElseInLoopWithReadResolvedInOuterScope)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ADD, {1}, {in0, 1}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ADD, {2}, {1, in1}, {}},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_MOV, {out0}, {2}, {}},
|
||||
{ TGSI_OPCODE_END}
|
||||
};
|
||||
run (code, temp_lt_expect({{-1,-1}, {2,9}, {9, 11}}));
|
||||
}
|
||||
|
||||
/* Here the nested if condition is of no consequence to the life time
|
||||
* because the variable was already written in the enclosing else-branch.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorExactTest, NestedIfElseInLoopResolvedInOuterScope2)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ADD, {2}, {1, in1}, {}},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_MOV, {out0}, {2}, {}},
|
||||
{ TGSI_OPCODE_END}
|
||||
};
|
||||
run (code, temp_lt_expect({{-1,-1}, {2,9}, {9, 11}}));
|
||||
}
|
||||
|
||||
/* Test that tracking of IF/ELSE scopes does not unnessesarily cross loops,
|
||||
* i.e. if the inner IF/ELSE pair is enclosed by a loop which is enclosed
|
||||
* by another IF statement: The resolution of unconditionality of the write
|
||||
* within the loop is not changed by the fact that the loop is enclosed by
|
||||
* an IF scope.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorExactTest, NestedIfInLoopAlwaysWriteParentIfOutsideLoop)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_MOV, {2}, {1}, {}},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {2}, {in1}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_MOV, {out0}, {2}, {}},
|
||||
|
||||
{ TGSI_OPCODE_END}
|
||||
};
|
||||
run (code, temp_lt_expect({{-1,-1}, {3,12}, {12, 17}}));
|
||||
}
|
||||
|
||||
/* The value is written in a loop and in a nested IF, but
|
||||
* not in all code paths, hence the value must survive the loop.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorExactTest, NestedIfInLoopWriteNotAlways)
|
||||
|
|
@ -316,6 +618,183 @@ TEST_F(LifetimeEvaluatorExactTest, NestedIfInLoopWriteNotAlways)
|
|||
run (code, temp_lt_expect({{-1,-1}, {0,13}}));
|
||||
}
|
||||
|
||||
/* Test that reading in an ELSE branach after writing is ignored:
|
||||
* The value is written in a loop in both branches of if-else but also
|
||||
* read in the else after writing, should have no effect on lifetime.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorExactTest, IfElseWriteInLoopAlsoReadInElse)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in1}, {}},
|
||||
{ TGSI_OPCODE_MUL, {1}, {in0, 1}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_MOV, {out0}, {1}, {}},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_END}
|
||||
};
|
||||
run (code, temp_lt_expect({{-1,-1}, {2,7}}));
|
||||
}
|
||||
|
||||
/* Test that a write in an inner IF/ELSE pair is propagated to the outer
|
||||
* ELSE branch: The value is written in a loop in both branches of a nested
|
||||
* IF/ELSE pair, but only within the outer else, hence in summary the write is
|
||||
* conditional within the loop.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorExactTest, WriteInNestedIfElseOuterElseOnly)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_ADD, {1}, {in1, in0}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_MOV, {out0}, {1}, {}},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_END}
|
||||
};
|
||||
run (code, temp_lt_expect({{-1,-1}, {0,10}}));
|
||||
}
|
||||
|
||||
/* Test that reads in an inner ELSE after write within the enclosing IF branch
|
||||
* is of no consequence (i.e. check that the read in the ELSE branch is not
|
||||
* attributed as read before write when the outer ELSE branch is scanned:
|
||||
* Nested if-else in loop. The value is written in the outer if and else and
|
||||
* read in one inner else, should limit lifetime.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorExactTest, WriteUnconditionallyReadInNestedElse)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {out1}, {1}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_MOV, {out0}, {1}, {}},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_END}
|
||||
};
|
||||
run (code, temp_lt_expect({{-1,-1}, {2,10}}));
|
||||
}
|
||||
|
||||
|
||||
/* Nested if-else in loop. The value is written in a loop in both branches
|
||||
* of if-else but also read in the second nested else before writing.
|
||||
* Is conditional.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorExactTest, NestedIfelseReadFirstInInnerElseInLoop)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in1}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_ADD, {1}, {in1, 1}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_MOV, {out0}, {1}, {}},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_END}
|
||||
};
|
||||
run (code, temp_lt_expect({{-1,-1}, {0,15}}));
|
||||
}
|
||||
|
||||
/* Test that read before write is properly tracked for nested IF branches.
|
||||
* The value is written in a loop in both branches of IF/ELSE but also read in
|
||||
* the second nested IF before writing - is conditional.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorExactTest, NestedIfelseReadFirstInInnerIfInLoop)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in1}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ADD, {1}, {in1, 1}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_MOV, {out0}, {1}, {}},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_END}
|
||||
};
|
||||
run (code, temp_lt_expect({{-1,-1}, {0,15}}));
|
||||
}
|
||||
|
||||
/* Same as above, but for the secondary ELSE branch:
|
||||
* The value is written in a loop in both branches of IF/ELSE but also read in
|
||||
* the second nested ELSE branch before writing - is conditional.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorExactTest, WriteInOneElseBranchReadFirstInOtherInLoop)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in1}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_ADD, {1}, {in1, 1}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_MOV, {out0}, {1}, {}},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_END}
|
||||
};
|
||||
run (code, temp_lt_expect({{-1,-1}, {2,11}}));
|
||||
}
|
||||
|
||||
/* Test that the "write is unconditional" resolution is not overwritten within
|
||||
* a loop: The value is written in a loop in both branches of an IF/ELSE clause,
|
||||
* hence the second IF doesn't make it conditional.
|
||||
*/
|
||||
TEST_F(LifetimeEvaluatorExactTest, WriteInIfElseBranchSecondIfInLoop)
|
||||
{
|
||||
const vector<FakeCodeline> code = {
|
||||
{ TGSI_OPCODE_BGNLOOP },
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ELSE},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in1}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_IF, {}, {in0}, {}},
|
||||
{ TGSI_OPCODE_MOV, {1}, {in0}, {}},
|
||||
{ TGSI_OPCODE_ENDIF},
|
||||
{ TGSI_OPCODE_MOV, {out0}, {1}, {}},
|
||||
{ TGSI_OPCODE_ENDLOOP },
|
||||
{ TGSI_OPCODE_END}
|
||||
};
|
||||
run (code, temp_lt_expect({{-1,-1}, {2,9}}));
|
||||
}
|
||||
|
||||
|
||||
/* A continue in the loop is not relevant */
|
||||
TEST_F(LifetimeEvaluatorExactTest, LoopWithWriteAfterContinue)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue