Repository: KhronosGroup/SPIRV-Tools (language: python)

Issue:
[spirv-opt] Inlining pass generates OpVariable of PhysicalStorageBuffer pointer type without AliasedPointer decoration.
If the source spirv contains a function that takes an AliasedPointer parameter, the `--inline-entry-points-exhaustive` pass generates a pointer-typed OpVariable without `AliasedPointer` decoration, which leads to validation error.

Steps to reproduce:
[test.zip](https://github.com/KhronosGroup/SPIRV-Tools/files/14553298/test.zip)

Use the `test.spv` in test.zip file:

```shell
spirv-val test.spv       # passes validation
spirv-opt --inline-entry-points-exhaustive -o test-out.spv
spirv-val test-out.spv       # FAILS validation
```

`spirv-val` output:
```
error: line 121: OpVariable 131: expected AliasedPointer or RestrictPointer for PhysicalStorageBuffer pointer.
  %131 = OpVariable %_ptr_Function__ptr_PhysicalStorageBuffer_int Function
```


Discussion / hints:
@dneto0 I believe @greg-lunarg worked on this. We'd be happy to look at this bug. Please assign to me if you'd like.

Fix patch:
diff --git a/source/opt/inline_pass.cpp b/source/opt/inline_pass.cpp
index 3f160b24cd..318643341a 100644
--- a/source/opt/inline_pass.cpp
+++ b/source/opt/inline_pass.cpp
@@ -213,6 +213,19 @@ uint32_t InlinePass::CreateReturnVar(
         {(uint32_t)spv::StorageClass::Function}}}));
   new_vars->push_back(std::move(var_inst));
   get_decoration_mgr()->CloneDecorations(calleeFn->result_id(), returnVarId);
+
+  // Decorate the return var with AliasedPointer if the storage class of the
+  // pointee type is PhysicalStorageBuffer.
+  auto const pointee_type =
+      type_mgr->GetType(returnVarTypeId)->AsPointer()->pointee_type();
+  if (pointee_type->AsPointer() != nullptr) {
+    if (pointee_type->AsPointer()->storage_class() ==
+        spv::StorageClass::PhysicalStorageBuffer) {
+      get_decoration_mgr()->AddDecoration(
+          returnVarId, uint32_t(spv::Decoration::AliasedPointer));
+    }
+  }
+
   return returnVarId;
 }
 


Test patch:
diff --git a/test/opt/inline_test.cpp b/test/opt/inline_test.cpp
index 1e5d9f3b4a..bf791811d5 100644
--- a/test/opt/inline_test.cpp
+++ b/test/opt/inline_test.cpp
@@ -4422,6 +4422,55 @@ OpFunctionEnd
   SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
 }
 
+TEST_F(InlineTest, DecorateReturnVariableWithAliasedPointer) {
+  const std::string text = R"(OpCapability Int64
+               OpCapability VariablePointers
+               OpCapability PhysicalStorageBufferAddresses
+               OpCapability Shader
+               OpExtension "SPV_KHR_storage_buffer_storage_class"
+               OpExtension "SPV_KHR_variable_pointers"
+               OpExtension "SPV_KHR_physical_storage_buffer"
+               OpMemoryModel PhysicalStorageBuffer64 GLSL450
+               OpEntryPoint GLCompute %1 "main"
+               OpExecutionMode %1 LocalSize 8 8 1
+               OpDecorate %_ptr_PhysicalStorageBuffer__struct_5 ArrayStride 8
+               OpMemberDecorate %_struct_3 0 Offset 0
+               OpMemberDecorate %_struct_3 1 Offset 8
+               OpDecorate %_ptr_PhysicalStorageBuffer_int ArrayStride 4
+               OpMemberDecorate %_struct_5 0 Offset 0
+               OpMemberDecorate %_struct_5 1 Offset 4
+               OpDecorate %6 Aliased
+; CHECK:       OpDecorate %22 AliasedPointer
+       %void = OpTypeVoid
+          %8 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %int_0 = OpConstant %int 0
+               OpTypeForwardPointer %_ptr_PhysicalStorageBuffer__struct_5 PhysicalStorageBuffer
+  %_struct_3 = OpTypeStruct %int %_ptr_PhysicalStorageBuffer__struct_5
+%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
+  %_struct_5 = OpTypeStruct %int %int
+         %11 = OpTypeFunction %_ptr_PhysicalStorageBuffer_int %_ptr_PhysicalStorageBuffer__struct_5
+%_ptr_PhysicalStorageBuffer__struct_5 = OpTypePointer PhysicalStorageBuffer %_struct_5
+%_ptr_Function__struct_3 = OpTypePointer Function %_struct_3
+          %1 = OpFunction %void None %8
+         %13 = OpLabel
+         %14 = OpVariable %_ptr_Function__struct_3 Function
+         %15 = OpLoad %_struct_3 %14
+         %16 = OpCompositeExtract %_ptr_PhysicalStorageBuffer__struct_5 %15 1
+         %17 = OpFunctionCall %_ptr_PhysicalStorageBuffer_int %18 %16
+               OpReturn
+               OpFunctionEnd
+         %18 = OpFunction %_ptr_PhysicalStorageBuffer_int None %11
+          %6 = OpFunctionParameter %_ptr_PhysicalStorageBuffer__struct_5
+         %19 = OpLabel
+         %20 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %6 %int_0
+               OpReturnValue %20
+               OpFunctionEnd)";
+
+  SetTargetEnv(SPV_ENV_VULKAN_1_2);
+  SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
+}
+
 // TODO(greg-lunarg): Add tests to verify handling of these cases:
 //
 //    Empty modules