[spirv-reader] Avoid creating access with no indices
If an `OpAccessChain` instruction has no indices, just forward the
source object instead of creating an empty `access` instruction.
Simplify the two downstream transforms accordingly.
Bug: 370743660
Change-Id: I26e9c5c09d4b22cdeb45c6d2f08727fce0c46f37
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/211097
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Commit-Queue: James Price <jrprice@google.com>
diff --git a/src/tint/lang/spirv/reader/lower/shader_io.cc b/src/tint/lang/spirv/reader/lower/shader_io.cc
index 7fc8d18..24d4601 100644
--- a/src/tint/lang/spirv/reader/lower/shader_io.cc
+++ b/src/tint/lang/spirv/reader/lower/shader_io.cc
@@ -280,16 +280,10 @@
to_destroy.Push(lve);
},
[&](core::ir::Access* a) {
- if (!a->Indices().IsEmpty()) {
- // Remove the pointer from the source and destination type.
- a->SetOperand(core::ir::Access::kObjectOperandOffset, object);
- a->Result(0)->SetType(a->Result(0)->Type()->UnwrapPtr());
- ReplaceInputPointerUses(var, a->Result(0));
- } else {
- // Fold the access away and replace its uses.
- ReplaceInputPointerUses(var, a->Result(0));
- to_destroy.Push(a);
- }
+ // Remove the pointer from the source and destination type.
+ a->SetOperand(core::ir::Access::kObjectOperandOffset, object);
+ a->Result(0)->SetType(a->Result(0)->Type()->UnwrapPtr());
+ ReplaceInputPointerUses(var, a->Result(0));
},
TINT_ICE_ON_NO_MATCH);
});
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 8afe5e2..9647fbf 100644
--- a/src/tint/lang/spirv/reader/lower/shader_io_test.cc
+++ b/src/tint/lang/spirv/reader/lower/shader_io_test.cc
@@ -645,59 +645,6 @@
EXPECT_EQ(expect, str());
}
-TEST_F(SpirvReader_ShaderIOTest, Input_AccessChains) {
- auto* lid = b.Var("lid", ty.ptr(core::AddressSpace::kIn, ty.vec3<u32>()));
- {
- core::IOAttributes attributes;
- attributes.builtin = core::BuiltinValue::kLocalInvocationId;
- lid->SetAttributes(std::move(attributes));
- }
- mod.root_block->Append(lid);
-
- auto* ep = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kCompute);
- ep->SetWorkgroupSize(1, 1, 1);
- b.Append(ep->Block(), [&] {
- auto* access_1 = b.Access(ty.ptr(core::AddressSpace::kIn, ty.vec3<u32>()), lid);
- auto* access_2 = b.Access(ty.ptr(core::AddressSpace::kIn, ty.vec3<u32>()), access_1);
- auto* vec = b.Load(access_2);
- auto* z = b.LoadVectorElement(access_2, 2_u);
- b.Multiply<vec3<u32>>(vec, z);
- b.Return(ep);
- });
-
- auto* src = R"(
-$B1: { # root
- %lid:ptr<__in, vec3<u32>, read> = var @builtin(local_invocation_id)
-}
-
-%foo = @compute @workgroup_size(1, 1, 1) func():void {
- $B2: {
- %3:ptr<__in, vec3<u32>, read> = access %lid
- %4:ptr<__in, vec3<u32>, read> = access %3
- %5:vec3<u32> = load %4
- %6:u32 = load_vector_element %4, 2u
- %7:vec3<u32> = mul %5, %6
- ret
- }
-}
-)";
- EXPECT_EQ(src, str());
-
- auto* expect = R"(
-%foo = @compute @workgroup_size(1, 1, 1) func(%lid:vec3<u32> [@local_invocation_id]):void {
- $B1: {
- %3:u32 = access %lid, 2u
- %4:vec3<u32> = mul %lid, %3
- ret
- }
-}
-)";
-
- Run(ShaderIO);
-
- EXPECT_EQ(expect, str());
-}
-
TEST_F(SpirvReader_ShaderIOTest, Inputs_Struct_LocationOnEachMember) {
auto* colors_str = ty.Struct(
mod.symbols.New("Colors"),
@@ -2035,72 +1982,6 @@
EXPECT_EQ(expect, str());
}
-TEST_F(SpirvReader_ShaderIOTest, Output_AccessChain) {
- auto* color = b.Var("color", ty.ptr(core::AddressSpace::kOut, ty.vec4<f32>()));
- {
- core::IOAttributes attributes;
- attributes.location = 1u;
- color->SetAttributes(std::move(attributes));
- }
- mod.root_block->Append(color);
-
- auto* ep = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
- b.Append(ep->Block(), [&] { //
- auto* access_1 = b.Access(ty.ptr(core::AddressSpace::kOut, ty.vec4<f32>()), color);
- auto* access_2 = b.Access(ty.ptr(core::AddressSpace::kOut, ty.vec4<f32>()), access_1);
- auto* load = b.LoadVectorElement(access_2, 2_u);
- auto* mul = b.Multiply<vec4<f32>>(b.Splat<vec4<f32>>(1_f), load);
- b.Store(access_2, mul);
- b.Return(ep);
- });
-
- auto* src = R"(
-$B1: { # root
- %color:ptr<__out, vec4<f32>, read_write> = var @location(1)
-}
-
-%foo = @fragment func():void {
- $B2: {
- %3:ptr<__out, vec4<f32>, read_write> = access %color
- %4:ptr<__out, vec4<f32>, read_write> = access %3
- %5:f32 = load_vector_element %4, 2u
- %6:vec4<f32> = mul vec4<f32>(1.0f), %5
- store %4, %6
- ret
- }
-}
-)";
- EXPECT_EQ(src, str());
-
- auto* expect = R"(
-$B1: { # root
- %color:ptr<private, vec4<f32>, read_write> = var
-}
-
-%foo_inner = func():void {
- $B2: {
- %3:ptr<private, vec4<f32>, read_write> = access %color
- %4:ptr<private, vec4<f32>, read_write> = access %3
- %5:f32 = load_vector_element %4, 2u
- %6:vec4<f32> = mul vec4<f32>(1.0f), %5
- store %4, %6
- ret
- }
-}
-%foo = @fragment func():vec4<f32> [@location(1)] {
- $B3: {
- %8:void = call %foo_inner
- %9:vec4<f32> = load %color
- ret %9
- }
-}
-)";
-
- Run(ShaderIO);
-
- EXPECT_EQ(expect, str());
-}
-
TEST_F(SpirvReader_ShaderIOTest, Inputs_And_Outputs) {
auto* position = b.Var("position", ty.ptr(core::AddressSpace::kIn, ty.vec4<f32>()));
{
diff --git a/src/tint/lang/spirv/reader/lower/vector_element_pointer.cc b/src/tint/lang/spirv/reader/lower/vector_element_pointer.cc
index 97acad5..fa84275 100644
--- a/src/tint/lang/spirv/reader/lower/vector_element_pointer.cc
+++ b/src/tint/lang/spirv/reader/lower/vector_element_pointer.cc
@@ -140,11 +140,6 @@
sve->InsertBefore(store);
to_destroy.Push(store);
},
- [&](core::ir::Access* noop_access) {
- TINT_ASSERT(noop_access->Indices().IsEmpty());
- ReplaceAccessUses(noop_access, object, index);
- to_destroy.Push(noop_access);
- },
TINT_ICE_ON_NO_MATCH);
});
diff --git a/src/tint/lang/spirv/reader/lower/vector_element_pointer_test.cc b/src/tint/lang/spirv/reader/lower/vector_element_pointer_test.cc
index 640563f..710560f 100644
--- a/src/tint/lang/spirv/reader/lower/vector_element_pointer_test.cc
+++ b/src/tint/lang/spirv/reader/lower/vector_element_pointer_test.cc
@@ -65,64 +65,6 @@
EXPECT_EQ(expect, str());
}
-TEST_F(SpirvReader_VectorElementPointerTest, Access_NoIndices) {
- auto* foo = b.Function("foo", ty.vec4<u32>());
- b.Append(foo->Block(), [&] {
- auto* vec = b.Var<function, vec4<u32>>("vec");
- auto* access = b.Access<ptr<function, vec4<u32>>>(vec);
- b.Return(foo, b.Load(access));
- });
-
- auto* src = R"(
-%foo = func():vec4<u32> {
- $B1: {
- %vec:ptr<function, vec4<u32>, read_write> = var
- %3:ptr<function, vec4<u32>, read_write> = access %vec
- %4:vec4<u32> = load %3
- ret %4
- }
-}
-)";
- EXPECT_EQ(src, str());
-
- auto* expect = src;
-
- Run(VectorElementPointer);
-
- EXPECT_EQ(expect, str());
-}
-
-TEST_F(SpirvReader_VectorElementPointerTest, Access_NoIndices_Chain) {
- auto* foo = b.Function("foo", ty.vec4<u32>());
- b.Append(foo->Block(), [&] {
- auto* vec = b.Var<function, vec4<u32>>("vec");
- auto* access_1 = b.Access<ptr<function, vec4<u32>>>(vec);
- auto* access_2 = b.Access<ptr<function, vec4<u32>>>(access_1);
- auto* access_3 = b.Access<ptr<function, vec4<u32>>>(access_2);
- b.Return(foo, b.Load(access_3));
- });
-
- auto* src = R"(
-%foo = func():vec4<u32> {
- $B1: {
- %vec:ptr<function, vec4<u32>, read_write> = var
- %3:ptr<function, vec4<u32>, read_write> = access %vec
- %4:ptr<function, vec4<u32>, read_write> = access %3
- %5:ptr<function, vec4<u32>, read_write> = access %4
- %6:vec4<u32> = load %5
- ret %6
- }
-}
-)";
- EXPECT_EQ(src, str());
-
- auto* expect = src;
-
- Run(VectorElementPointer);
-
- EXPECT_EQ(expect, str());
-}
-
TEST_F(SpirvReader_VectorElementPointerTest, Access_Component_NoUse) {
auto* foo = b.Function("foo", ty.void_());
b.Append(foo->Block(), [&] {
@@ -278,44 +220,6 @@
EXPECT_EQ(expect, str());
}
-TEST_F(SpirvReader_VectorElementPointerTest, AccessBeforeUse) {
- auto* foo = b.Function("foo", ty.void_());
- b.Append(foo->Block(), [&] {
- auto* vec = b.Var<function, vec4<u32>>("vec");
- auto* access_1 = b.Access<ptr<function, u32>>(vec, 2_u);
- auto* access_2 = b.Access<ptr<function, u32>>(access_1);
- b.Store(access_2, 42_u);
- b.Return(foo);
- });
-
- auto* src = R"(
-%foo = func():void {
- $B1: {
- %vec:ptr<function, vec4<u32>, read_write> = var
- %3:ptr<function, u32, read_write> = access %vec, 2u
- %4:ptr<function, u32, read_write> = access %3
- store %4, 42u
- ret
- }
-}
-)";
- EXPECT_EQ(src, str());
-
- auto* expect = R"(
-%foo = func():void {
- $B1: {
- %vec:ptr<function, vec4<u32>, read_write> = var
- store_vector_element %vec, 2u, 42u
- ret
- }
-}
-)";
-
- Run(VectorElementPointer);
-
- EXPECT_EQ(expect, str());
-}
-
TEST_F(SpirvReader_VectorElementPointerTest, MultipleUses) {
auto* foo = b.Function("foo", ty.void_());
b.Append(foo->Block(), [&] {
diff --git a/src/tint/lang/spirv/reader/parser/memory_test.cc b/src/tint/lang/spirv/reader/parser/memory_test.cc
index 90e4945..9133ce5 100644
--- a/src/tint/lang/spirv/reader/parser/memory_test.cc
+++ b/src/tint/lang/spirv/reader/parser/memory_test.cc
@@ -726,9 +726,7 @@
%main = @compute @workgroup_size(1, 1, 1) func():void {
$B1: {
%2:ptr<function, u32, read_write> = var
- %3:ptr<function, u32, read_write> = access %2
- %4:ptr<function, u32, read_write> = access %3
- %5:u32 = load %4
+ %3:u32 = load %2
ret
}
)");
diff --git a/src/tint/lang/spirv/reader/parser/parser.cc b/src/tint/lang/spirv/reader/parser/parser.cc
index 9a4094f..81117c8 100644
--- a/src/tint/lang/spirv/reader/parser/parser.cc
+++ b/src/tint/lang/spirv/reader/parser/parser.cc
@@ -549,6 +549,12 @@
}
auto* base = Value(inst.GetSingleWordOperand(2));
+ if (indices.IsEmpty()) {
+ // There are no indices, so just forward the base object.
+ AddValue(inst.result_id(), base);
+ return;
+ }
+
// Propagate the access mode of the base object.
auto access_mode = core::Access::kUndefined;
if (auto* ptr = base->Type()->As<core::type::Pointer>()) {