mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-10-18 11:10:05 +00:00
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:
parent
d5a3bfcf2f
commit
92fe420c8a
@ -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>(
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user