tint/transform: Fix PromoteInitializersToLetTest for materialized constants

PromoteInitializersToLet was not handling sem::Materialize nodes.
This can happen for const arrays when they are dynamically indexed.

Fixed: tint:1653
Change-Id: I3d67d8139e481c89b31a3a30c7ef44384b7545ba
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/99500
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Ben Clayton
2022-08-17 17:26:41 +00:00
committed by Dawn LUCI CQ
parent 873f92e741
commit 0f0ba20208
9 changed files with 205 additions and 12 deletions

View File

@@ -75,19 +75,22 @@ void PromoteInitializersToLet::Run(CloneContext& ctx, const DataMap&, DataMap&)
return true;
},
[&](const ast::IdentifierExpression* expr) {
if (auto* user = ctx.src->Sem().Get<sem::VariableUser>(expr)) {
// Identifier resolves to a variable
if (auto* stmt = user->Stmt()) {
if (auto* decl = stmt->Declaration()->As<ast::VariableDeclStatement>();
decl && decl->variable->Is<ast::Const>()) {
// The identifier is used on the RHS of a 'const' declaration. Ignore.
return true;
if (auto* sem = ctx.src->Sem().Get(expr)) {
if (auto* user = sem->UnwrapMaterialize()->As<sem::VariableUser>()) {
// Identifier resolves to a variable
if (auto* stmt = user->Stmt()) {
if (auto* decl = stmt->Declaration()->As<ast::VariableDeclStatement>();
decl && decl->variable->Is<ast::Const>()) {
// The identifier is used on the RHS of a 'const' declaration.
// Ignore.
return true;
}
}
if (user->Variable()->Declaration()->Is<ast::Const>()) {
// The identifier resolves to a 'const' variable, but isn't used to
// initialize another 'const'. This needs promoting.
return promote(user);
}
}
if (user->Variable()->Declaration()->Is<ast::Const>()) {
// The identifier resolves to a 'const' variable, but isn't used to
// initialize another 'const'. This needs promoting.
return promote(user);
}
}
return true;

View File

@@ -158,6 +158,37 @@ fn f() {
EXPECT_EQ(expect, str(got));
}
TEST_F(PromoteInitializersToLetTest, GlobalConstArrayDynamicIndex) {
auto* src = R"(
const TRI_VERTICES = array(
vec4(0., 0., 0., 1.),
vec4(0., 1., 0., 1.),
vec4(1., 1., 0., 1.),
);
@vertex
fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4<f32> {
// note: TRI_VERTICES requires a materialize before the dynamic index.
return TRI_VERTICES[in_vertex_index];
}
)";
auto* expect = R"(
const TRI_VERTICES = array(vec4(0.0, 0.0, 0.0, 1.0), vec4(0.0, 1.0, 0.0, 1.0), vec4(1.0, 1.0, 0.0, 1.0));
@vertex
fn vs_main(@builtin(vertex_index) in_vertex_index : u32) -> @builtin(position) vec4<f32> {
let tint_symbol = TRI_VERTICES;
return tint_symbol[in_vertex_index];
}
)";
DataMap data;
auto got = Run<PromoteInitializersToLet>(src);
EXPECT_EQ(expect, str(got));
}
TEST_F(PromoteInitializersToLetTest, GlobalConstBasicArray_OutOfOrder) {
auto* src = R"(
fn f() {