Fix PromoteSideEffectsToDeclTest converting for loop to loop with nested hoisted lets

When converting a for-loop to a loop, we were not cloning the for-loop's
body, but rather the statements within it. This worked fine, except if
we also hoisted a variable to a let within that body, which requires the
body to be cloned for the 'insert before' to work. This change clones
the for-loop body, which fixes the problem, but introduces a block in
the destination AST, which is ugly, but not incorrect.

Bug: tint:1300
Change-Id: I478244d87f8cf58837102004242ba1c835e21710
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/78821
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
Antonio Maiorano 2022-02-02 14:33:32 +00:00 committed by Tint LUCI CQ
parent b80e2f3b6e
commit e1699caf81
14 changed files with 82 additions and 7 deletions

View File

@ -242,9 +242,7 @@ class PromoteSideEffectsToDecl::State {
body_stmts.emplace_back(b.If(not_cond, break_body));
}
// Next emit the for-loop body
for (auto* body_stmt : for_loop->body->statements) {
body_stmts.emplace_back(ctx.Clone(body_stmt));
}
body_stmts.emplace_back(ctx.Clone(for_loop->body));
// Finally create the continuing block if there was one.
const ast::BlockStatement* continuing = nullptr;

View File

@ -184,7 +184,9 @@ fn f() {
if (!((f == tint_symbol[0]))) {
break;
}
var marker = 1;
{
var marker = 1;
}
continuing {
f = (f + 1.0);
@ -218,7 +220,9 @@ fn f() {
if (!((f < 10.0))) {
break;
}
var marker = 1;
{
var marker = 1;
}
continuing {
let tint_symbol = array<f32, 1u>(1.0);
@ -257,7 +261,9 @@ fn f() {
if (!((f < tint_symbol_1[0]))) {
break;
}
var marker = 1;
{
var marker = 1;
}
continuing {
let tint_symbol_2 = array<f32, 1u>(2.0);
@ -678,7 +684,9 @@ fn f() {
if (!((var_for_index[i] < 3))) {
break;
}
break;
{
break;
}
}
}
)";
@ -712,9 +720,54 @@ fn f() {
if (!((var_for_index[i].x < 3.0))) {
break;
}
{
break;
}
}
}
)";
DataMap data;
data.Add<PromoteSideEffectsToDecl::Config>(/* type_ctor_to_let */ false,
/* dynamic_index_to_var */ true);
auto got = Run<PromoteSideEffectsToDecl>(src, data);
EXPECT_EQ(expect, str(got));
}
TEST_F(PromoteSideEffectsToDeclTest,
DynamicIndexToVar_MatrixIndexInForLoopCondWithNestedIndex) {
auto* src = R"(
fn f() {
var i : i32;
let p = mat2x2(1.0, 2.0, 3.0, 4.0);
for(; p[i].x < 3.0; ) {
if (p[i].x < 1.0) {
var marker = 1;
}
break;
}
}
)";
auto* expect = R"(
fn f() {
var i : i32;
let p = mat2x2(1.0, 2.0, 3.0, 4.0);
loop {
var var_for_index = p;
if (!((var_for_index[i].x < 3.0))) {
break;
}
{
var var_for_index_1 = p;
if ((var_for_index_1[i].x < 1.0)) {
var marker = 1;
}
break;
}
}
}
)";
DataMap data;

View File

@ -12,6 +12,8 @@ void f() {
if (!((i < tint_symbol[0]))) {
break;
}
{
}
}
}

View File

@ -10,5 +10,7 @@ void f() {
if (!((i < tint_symbol[0]))) {
break;
}
{
}
}
}

View File

@ -12,6 +12,8 @@ void f() {
if (!((i < tint_symbol.arr[0]))) {
break;
}
{
}
}
}

View File

@ -16,6 +16,8 @@ void f() {
if (!((i < tint_symbol.i))) {
break;
}
{
}
}
}

View File

@ -14,5 +14,7 @@ void f() {
if (!((i < tint_symbol.i))) {
break;
}
{
}
}
}

View File

@ -12,6 +12,8 @@ void f() {
if (!((i < tint_symbol.i))) {
break;
}
{
}
}
}

View File

@ -11,6 +11,8 @@ void f() {
if (!(false)) {
break;
}
{
}
{
int tint_symbol[1] = int[1](1);
i = (i + tint_symbol[0]);

View File

@ -9,6 +9,8 @@ void f() {
if (!(false)) {
break;
}
{
}
{
const int tint_symbol[1] = {1};
i = (i + tint_symbol[0]);

View File

@ -11,6 +11,8 @@ void f() {
if (!(false)) {
break;
}
{
}
{
tint_array_wrapper const tint_symbol = {.arr={1}};
i = as_type<int>((as_type<uint>(i) + as_type<uint>(tint_symbol.arr[0])));

View File

@ -16,6 +16,8 @@ void f() {
if (!(false)) {
break;
}
{
}
{
S tint_symbol = S(1);
i = (i + tint_symbol.i);

View File

@ -14,6 +14,8 @@ void f() {
if (!(false)) {
break;
}
{
}
{
const S tint_symbol = {1};
i = (i + tint_symbol.i);

View File

@ -12,6 +12,8 @@ void f() {
if (!(false)) {
break;
}
{
}
{
S const tint_symbol = {.i=1};
i = as_type<int>((as_type<uint>(i) + as_type<uint>(tint_symbol.i)));