Reduce load size does not work for array with spec const size (#4845)

Arrays do not have to have a size that is known at compile time.  It
could be a spec constant.  In these cases, treat the array
as if it is arbitrarily long.  This commit will treat it like it is an
array of size UINT32_MAX.

Fixes https://crbug.com/oss-fuzz/47397.
This commit is contained in:
Steven Perron 2022-07-05 16:16:50 -04:00 committed by GitHub
parent d5a3bfcf2f
commit 92fe420c8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 2 deletions

View File

@ -161,8 +161,15 @@ bool ReduceLoadSize::ShouldReplaceExtract(Instruction* inst) {
case analysis::Type::kArray: {
const analysis::Constant* size_const =
const_mgr->FindDeclaredConstant(load_type->AsArray()->LengthId());
assert(size_const->AsIntConstant());
total_size = size_const->GetU32();
if (size_const) {
assert(size_const->AsIntConstant());
total_size = size_const->GetU32();
} else {
// The size is spec constant, so it is unknown at this time. Assume
// it is very large.
total_size = UINT32_MAX;
}
} break;
case analysis::Type::kStruct:
total_size = static_cast<uint32_t>(

View File

@ -498,6 +498,45 @@ TEST_F(ReduceLoadSizeTest, replace_cbuffer_load_fully_used) {
SinglePassRunAndMatch<ReduceLoadSize>(test, false, 1.1);
}
TEST_F(ReduceLoadSizeTest, replace_array_with_spec_constant_size) {
const std::string test =
R"(
OpCapability ClipDistance
OpExtension " "
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %1 " "
OpExecutionMode %1 OriginUpperLeft
%void = OpTypeVoid
%3 = OpTypeFunction %void
%int = OpTypeInt 32 1
%uint = OpTypeInt 32 0
%6 = OpSpecConstant %uint 538976288
%_arr_int_6 = OpTypeArray %int %6
%_struct_8 = OpTypeStruct %_arr_int_6
%_struct_9 = OpTypeStruct %_struct_8
%_ptr_Uniform__struct_9 = OpTypePointer Uniform %_struct_9
; CHECK: [[var:%\w+]] = OpVariable %_ptr_Uniform__struct_9 Uniform
%11 = OpVariable %_ptr_Uniform__struct_9 Uniform
%int_0 = OpConstant %int 0
%_ptr_Uniform__arr_int_6 = OpTypePointer Uniform %_arr_int_6
%1 = OpFunction %void None %3
%14 = OpLabel
; CHECK: [[ac:%\w+]] = OpAccessChain %_ptr_Uniform__arr_int_6 [[var]] %int_0 %int_0
; CHECK: [[new_ac:%\w+]] = OpAccessChain %_ptr_Uniform_int [[ac]] %uint_538976288
; CHECK: [[ld:%\w+]] = OpLoad %int [[new_ac]]
; CHECK: %18 = OpIAdd %int [[ld]] [[ld]]
%15 = OpAccessChain %_ptr_Uniform__arr_int_6 %11 %int_0 %int_0
%16 = OpLoad %_arr_int_6 %15
%17 = OpCompositeExtract %int %16 538976288
%18 = OpIAdd %int %17 %17
OpUnreachable
OpFunctionEnd
)";
SinglePassRunAndMatch<ReduceLoadSize>(test, false,
kDefaultLoadReductionThreshold);
}
} // namespace
} // namespace opt
} // namespace spvtools