mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-26 21:30:07 +00:00
Handle access chain with no index in SROA. (#2304)
It is legal, but not generated by any SPIR-V producer: an OpAccessChain with no indexes. This is essentially just a copy of the pointer. I have decided to treat it like an OpCopyObject. In CheckUses, we return that it is not okay. When looking at this I realized that we had code in GetUsedComponents that cannot be reached. If there is a use in an OpCopyObject the it will not call GetUsedComponents. I removed that dead code. Fixes https://crbug.com/918311.
This commit is contained in:
parent
213e15e100
commit
81fb2649bf
@ -638,8 +638,8 @@ bool ScalarReplacementPass::CheckUses(const Instruction* inst,
|
||||
switch (user->opcode()) {
|
||||
case SpvOpAccessChain:
|
||||
case SpvOpInBoundsAccessChain:
|
||||
if (index == 2u) {
|
||||
uint32_t id = user->GetSingleWordOperand(3u);
|
||||
if (index == 2u && user->NumInOperands() > 1) {
|
||||
uint32_t id = user->GetSingleWordInOperand(1u);
|
||||
const Instruction* opInst = get_def_use_mgr()->GetDef(id);
|
||||
if (!IsCompileTimeConstantInst(opInst->opcode())) {
|
||||
ok = false;
|
||||
@ -783,16 +783,6 @@ ScalarReplacementPass::GetUsedComponents(Instruction* inst) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
case SpvOpCopyObject: {
|
||||
// Follow the copy to see which components are used.
|
||||
auto t = GetUsedComponents(use);
|
||||
if (!t) {
|
||||
result.reset(nullptr);
|
||||
return false;
|
||||
}
|
||||
result->insert(t->begin(), t->end());
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
// We do not know what is happening. Have to assume the worst.
|
||||
result.reset(nullptr);
|
||||
|
@ -1593,6 +1593,33 @@ TEST_F(ScalarReplacementTest, AmbigousPointer) {
|
||||
SinglePassRunAndMatch<ScalarReplacementPass>(text, true);
|
||||
}
|
||||
|
||||
// Test that scalar replacement does not crash when there is an OpAccessChain
|
||||
// with no index. If we choose to handle this case in the future, then the
|
||||
// result can change.
|
||||
TEST_F(ScalarReplacementTest, TestAccessChainWithNoIndexes) {
|
||||
const std::string text = R"(
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %1 "main"
|
||||
OpExecutionMode %1 OriginLowerLeft
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%_struct_5 = OpTypeStruct %float
|
||||
%_ptr_Function__struct_5 = OpTypePointer Function %_struct_5
|
||||
%1 = OpFunction %void None %3
|
||||
%7 = OpLabel
|
||||
%8 = OpVariable %_ptr_Function__struct_5 Function
|
||||
%9 = OpAccessChain %_ptr_Function__struct_5 %8
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
auto result =
|
||||
SinglePassRunAndDisassemble<ScalarReplacementPass>(text, true, false);
|
||||
EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace opt
|
||||
} // namespace spvtools
|
||||
|
Loading…
Reference in New Issue
Block a user