Skip to content

Commit

Permalink
opt: support 64-bit OpAccessChain index in FixStorageClass (#5446)
Browse files Browse the repository at this point in the history
The SPIR-V specification allows any scalar integer type as an index. DXC
usually emits indexes as 32-bit integer types, however, in some cases it
is possible to make it emit 64-bit indexes instead (as in
microsoft/DirectXShaderCompiler#5638).
  • Loading branch information
cassiebeckley authored Oct 19, 2023
1 parent 5084f58 commit 73876de
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
8 changes: 7 additions & 1 deletion source/opt/fix_storage_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,13 @@ uint32_t FixStorageClass::WalkAccessChainType(Instruction* inst, uint32_t id) {
const analysis::Constant* index_const =
context()->get_constant_mgr()->FindDeclaredConstant(
inst->GetSingleWordInOperand(i));
uint32_t index = index_const->GetU32();
// It is highly unlikely that any type would have more fields than could
// be indexed by a 32-bit integer, and GetSingleWordInOperand only takes
// a 32-bit value, so we would not be able to handle it anyway. But the
// specification does allow any scalar integer type, treated as signed,
// so we simply downcast the index to 32-bits.
uint32_t index =
static_cast<uint32_t>(index_const->GetSignExtendedValue());
id = type_inst->GetSingleWordInOperand(index);
break;
}
Expand Down
41 changes: 41 additions & 0 deletions test/opt/fix_storage_class_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,47 @@ TEST_F(FixTypeTest, FixPhiInLoop) {

SinglePassRunAndMatch<FixStorageClass>(text, false);
}
TEST_F(FixStorageClassTest, SupportsU64Index) {
const std::string text = R"(
; CHECK: OpAccessChain %_ptr_Uniform_float
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %1 "testMain" %gl_LocalInvocationID
OpExecutionMode %1 LocalSize 8 8 1
OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
OpDecorate %8 DescriptorSet 0
OpDecorate %8 Binding 0
OpDecorate %_runtimearr_float ArrayStride 4
OpMemberDecorate %_struct_7 0 Offset 0
OpDecorate %_struct_7 BufferBlock
%ulong = OpTypeInt 64 0
%ulong_0 = OpConstant %ulong 0
%float = OpTypeFloat 32
%float_123 = OpConstant %float 123
%uint = OpTypeInt 32 0
%uint_10 = OpConstant %uint 10
%_runtimearr_float = OpTypeRuntimeArray %float
%_struct_7 = OpTypeStruct %_runtimearr_float
%_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
%v3uint = OpTypeVector %uint 3
%_ptr_Input_v3uint = OpTypePointer Input %v3uint
%void = OpTypeVoid
%30 = OpTypeFunction %void
%_ptr_Uniform_float = OpTypePointer Uniform %float
%8 = OpVariable %_ptr_Uniform__struct_7 Uniform
%gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
%1 = OpFunction %void None %30
%38 = OpLabel
%44 = OpLoad %v3uint %gl_LocalInvocationID
%59 = OpCompositeExtract %uint %44 0
%60 = OpAccessChain %_ptr_Uniform_float %8 %ulong_0 %59
OpStore %60 %float_123
OpReturn
OpFunctionEnd
)";

SinglePassRunAndMatch<FixStorageClass>(text, false);
}

} // namespace
} // namespace opt
Expand Down

0 comments on commit 73876de

Please sign in to comment.