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:
Steven Perron 2019-01-18 14:19:43 -05:00 committed by GitHub
parent 213e15e100
commit 81fb2649bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 12 deletions

View File

@ -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);

View File

@ -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