[spirv-reader][ir] Allow propagating vars through lets.
In the SPIR-V reader lowering ShaderIO when processing the `var`s which
have been re-written, allow to propagate the `var` through a `let`. This
can happen if you do an `OpCopyObject` on the `OpVariable` which creates
a let.
Bug: 42250952
Change-Id: Ia07389fe6b7d2b3e424b54e7459e8d6f662e4131
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/246714
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/spirv/reader/lower/shader_io.cc b/src/tint/lang/spirv/reader/lower/shader_io.cc
index 3139baf..0bf4231 100644
--- a/src/tint/lang/spirv/reader/lower/shader_io.cc
+++ b/src/tint/lang/spirv/reader/lower/shader_io.cc
@@ -142,8 +142,8 @@
// Update all uses of the module-scope variable.
value->ForEachUseUnsorted([&](core::ir::Usage use) {
- if (auto* access = use.instruction->As<core::ir::Access>()) {
- ReplaceOutputPointerAddressSpace(access->Result());
+ if (use.instruction->IsAnyOf<core::ir::Access, core::ir::Let>()) {
+ ReplaceOutputPointerAddressSpace(use.instruction->Result());
} else if (use.instruction->Is<core::ir::Phony>()) {
use.instruction->Destroy();
} else if (!use.instruction->IsAnyOf<core::ir::Load, core::ir::LoadVectorElement,
diff --git a/src/tint/lang/spirv/reader/lower/shader_io_test.cc b/src/tint/lang/spirv/reader/lower/shader_io_test.cc
index 0d54fda..ec60cb9 100644
--- a/src/tint/lang/spirv/reader/lower/shader_io_test.cc
+++ b/src/tint/lang/spirv/reader/lower/shader_io_test.cc
@@ -3420,5 +3420,60 @@
EXPECT_EQ(expect, str());
}
+
+TEST_F(SpirvReader_ShaderIOTest, Outputs_ThroughLet) {
+ auto* position = b.Var("position", ty.ptr(core::AddressSpace::kOut, ty.vec4<f32>()));
+ position->SetBuiltin(core::BuiltinValue::kPosition);
+
+ mod.root_block->Append(position);
+
+ auto* ep = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kVertex);
+ b.Append(ep->Block(), [&] { //
+ b.Let("tmp", position);
+ b.Store(position, b.Splat<vec4<f32>>(1_f));
+ b.Return(ep);
+ });
+
+ auto* src = R"(
+$B1: { # root
+ %position:ptr<__out, vec4<f32>, read_write> = var undef @builtin(position)
+}
+
+%foo = @vertex func():void {
+ $B2: {
+ %tmp:ptr<__out, vec4<f32>, read_write> = let %position
+ store %position, vec4<f32>(1.0f)
+ ret
+ }
+}
+)";
+ EXPECT_EQ(src, str());
+
+ auto* expect = R"(
+$B1: { # root
+ %position:ptr<private, vec4<f32>, read_write> = var undef
+}
+
+%foo_inner = func():void {
+ $B2: {
+ %tmp:ptr<private, vec4<f32>, read_write> = let %position
+ store %position, vec4<f32>(1.0f)
+ ret
+ }
+}
+%foo = @vertex func():vec4<f32> [@position] {
+ $B3: {
+ %5:void = call %foo_inner
+ %6:vec4<f32> = load %position
+ ret %6
+ }
+}
+)";
+
+ Run(ShaderIO);
+
+ EXPECT_EQ(expect, str());
+}
+
} // namespace
} // namespace tint::spirv::reader::lower