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>
diff --git a/src/transform/promote_side_effects_to_decl.cc b/src/transform/promote_side_effects_to_decl.cc
index 6274187..520e845 100644
--- a/src/transform/promote_side_effects_to_decl.cc
+++ b/src/transform/promote_side_effects_to_decl.cc
@@ -242,9 +242,7 @@
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;
diff --git a/src/transform/promote_side_effects_to_decl_test.cc b/src/transform/promote_side_effects_to_decl_test.cc
index 9c7a7fe..c520aa1 100644
--- a/src/transform/promote_side_effects_to_decl_test.cc
+++ b/src/transform/promote_side_effects_to_decl_test.cc
@@ -184,7 +184,9 @@
if (!((f == tint_symbol[0]))) {
break;
}
- var marker = 1;
+ {
+ var marker = 1;
+ }
continuing {
f = (f + 1.0);
@@ -218,7 +220,9 @@
if (!((f < 10.0))) {
break;
}
- var marker = 1;
+ {
+ var marker = 1;
+ }
continuing {
let tint_symbol = array<f32, 1u>(1.0);
@@ -257,7 +261,9 @@
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 @@
if (!((var_for_index[i] < 3))) {
break;
}
- break;
+ {
+ break;
+ }
}
}
)";
@@ -712,11 +720,56 @@
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;
data.Add<PromoteSideEffectsToDecl::Config>(/* type_ctor_to_let */ false,
/* dynamic_index_to_var */ true);
diff --git a/test/statements/for/condition/array_ctor.wgsl.expected.glsl b/test/statements/for/condition/array_ctor.wgsl.expected.glsl
index 42330bb..c02c4fb 100644
--- a/test/statements/for/condition/array_ctor.wgsl.expected.glsl
+++ b/test/statements/for/condition/array_ctor.wgsl.expected.glsl
@@ -12,6 +12,8 @@
if (!((i < tint_symbol[0]))) {
break;
}
+ {
+ }
}
}
diff --git a/test/statements/for/condition/array_ctor.wgsl.expected.hlsl b/test/statements/for/condition/array_ctor.wgsl.expected.hlsl
index 409e7c4..141cd27 100644
--- a/test/statements/for/condition/array_ctor.wgsl.expected.hlsl
+++ b/test/statements/for/condition/array_ctor.wgsl.expected.hlsl
@@ -10,5 +10,7 @@
if (!((i < tint_symbol[0]))) {
break;
}
+ {
+ }
}
}
diff --git a/test/statements/for/condition/array_ctor.wgsl.expected.msl b/test/statements/for/condition/array_ctor.wgsl.expected.msl
index 2ec1a68..5aefd59 100644
--- a/test/statements/for/condition/array_ctor.wgsl.expected.msl
+++ b/test/statements/for/condition/array_ctor.wgsl.expected.msl
@@ -12,6 +12,8 @@
if (!((i < tint_symbol.arr[0]))) {
break;
}
+ {
+ }
}
}
diff --git a/test/statements/for/condition/struct_ctor.wgsl.expected.glsl b/test/statements/for/condition/struct_ctor.wgsl.expected.glsl
index 853168f..ad8c2cb 100644
--- a/test/statements/for/condition/struct_ctor.wgsl.expected.glsl
+++ b/test/statements/for/condition/struct_ctor.wgsl.expected.glsl
@@ -16,6 +16,8 @@
if (!((i < tint_symbol.i))) {
break;
}
+ {
+ }
}
}
diff --git a/test/statements/for/condition/struct_ctor.wgsl.expected.hlsl b/test/statements/for/condition/struct_ctor.wgsl.expected.hlsl
index c9d9ff0..d80f79a 100644
--- a/test/statements/for/condition/struct_ctor.wgsl.expected.hlsl
+++ b/test/statements/for/condition/struct_ctor.wgsl.expected.hlsl
@@ -14,5 +14,7 @@
if (!((i < tint_symbol.i))) {
break;
}
+ {
+ }
}
}
diff --git a/test/statements/for/condition/struct_ctor.wgsl.expected.msl b/test/statements/for/condition/struct_ctor.wgsl.expected.msl
index a370f25..a89dfc2 100644
--- a/test/statements/for/condition/struct_ctor.wgsl.expected.msl
+++ b/test/statements/for/condition/struct_ctor.wgsl.expected.msl
@@ -12,6 +12,8 @@
if (!((i < tint_symbol.i))) {
break;
}
+ {
+ }
}
}
diff --git a/test/statements/for/continuing/array_ctor.wgsl.expected.glsl b/test/statements/for/continuing/array_ctor.wgsl.expected.glsl
index d40e419..76006fd 100644
--- a/test/statements/for/continuing/array_ctor.wgsl.expected.glsl
+++ b/test/statements/for/continuing/array_ctor.wgsl.expected.glsl
@@ -12,6 +12,8 @@
break;
}
{
+ }
+ {
int tint_symbol[1] = int[1](1);
i = (i + tint_symbol[0]);
}
diff --git a/test/statements/for/continuing/array_ctor.wgsl.expected.hlsl b/test/statements/for/continuing/array_ctor.wgsl.expected.hlsl
index e24b634..7348a72 100644
--- a/test/statements/for/continuing/array_ctor.wgsl.expected.hlsl
+++ b/test/statements/for/continuing/array_ctor.wgsl.expected.hlsl
@@ -10,6 +10,8 @@
break;
}
{
+ }
+ {
const int tint_symbol[1] = {1};
i = (i + tint_symbol[0]);
}
diff --git a/test/statements/for/continuing/array_ctor.wgsl.expected.msl b/test/statements/for/continuing/array_ctor.wgsl.expected.msl
index 5339dfa..ac6ffc2 100644
--- a/test/statements/for/continuing/array_ctor.wgsl.expected.msl
+++ b/test/statements/for/continuing/array_ctor.wgsl.expected.msl
@@ -12,6 +12,8 @@
break;
}
{
+ }
+ {
tint_array_wrapper const tint_symbol = {.arr={1}};
i = as_type<int>((as_type<uint>(i) + as_type<uint>(tint_symbol.arr[0])));
}
diff --git a/test/statements/for/continuing/struct_ctor.wgsl.expected.glsl b/test/statements/for/continuing/struct_ctor.wgsl.expected.glsl
index 014a37a..ca9a56c 100644
--- a/test/statements/for/continuing/struct_ctor.wgsl.expected.glsl
+++ b/test/statements/for/continuing/struct_ctor.wgsl.expected.glsl
@@ -17,6 +17,8 @@
break;
}
{
+ }
+ {
S tint_symbol = S(1);
i = (i + tint_symbol.i);
}
diff --git a/test/statements/for/continuing/struct_ctor.wgsl.expected.hlsl b/test/statements/for/continuing/struct_ctor.wgsl.expected.hlsl
index 671f26f..4dd0cf2 100644
--- a/test/statements/for/continuing/struct_ctor.wgsl.expected.hlsl
+++ b/test/statements/for/continuing/struct_ctor.wgsl.expected.hlsl
@@ -15,6 +15,8 @@
break;
}
{
+ }
+ {
const S tint_symbol = {1};
i = (i + tint_symbol.i);
}
diff --git a/test/statements/for/continuing/struct_ctor.wgsl.expected.msl b/test/statements/for/continuing/struct_ctor.wgsl.expected.msl
index a022488..08603f7 100644
--- a/test/statements/for/continuing/struct_ctor.wgsl.expected.msl
+++ b/test/statements/for/continuing/struct_ctor.wgsl.expected.msl
@@ -13,6 +13,8 @@
break;
}
{
+ }
+ {
S const tint_symbol = {.i=1};
i = as_type<int>((as_type<uint>(i) + as_type<uint>(tint_symbol.i)));
}