Ensure SROA gets the correct pointer type. (#2247)

We initially assumed that if the type manager returned the correct id
for the pointee type, that we would get the correct pointer type back,
but that is not true.  See the unit test added with this commit.  We
need to fall back to the linear search any time we are looking for a
pointer to a type that may not be unique.

At the same time, SROA considered an OpName on a variable to be a use of
the entire variable.  That has been fixed.

Fixes #2209.
This commit is contained in:
Steven Perron 2018-12-19 17:07:29 +00:00 committed by GitHub
parent 9e81c337f9
commit 9d04f82bef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 3 deletions

View File

@ -363,7 +363,7 @@ uint32_t ScalarReplacementPass::GetOrCreatePointerType(uint32_t id) {
context()->get_type_mgr()->GetTypeAndPointerType(id,
SpvStorageClassFunction);
uint32_t ptrId = 0;
if (id == context()->get_type_mgr()->GetId(pointeeTy)) {
if (pointeeTy->IsUniqueType()) {
// Non-ambiguous type, just ask the type manager for an id.
ptrId = context()->get_type_mgr()->GetTypeInstruction(pointerTy.get());
pointee_to_pointer_[id] = ptrId;
@ -751,8 +751,10 @@ ScalarReplacementPass::GetUsedComponents(Instruction* inst) {
return false;
}
}
case SpvOpName:
case SpvOpMemberName:
case SpvOpStore:
// No components are used. Things are just stored to.
// No components are used.
return true;
case SpvOpAccessChain:
case SpvOpInBoundsAccessChain: {

View File

@ -1149,7 +1149,6 @@ TEST_F(ScalarReplacementTest, NoPartialAccesses2) {
; CHECK: OpVariable [[float_ptr]] Function
; CHECK: OpVariable [[float_ptr]] Function
; CHECK: OpVariable [[float_ptr]] Function
; CHECK: OpVariable [[float_ptr]] Function
; CHECK-NOT: OpVariable
;
OpCapability Shader
@ -1555,6 +1554,45 @@ OpFunctionEnd
EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result));
}
TEST_F(ScalarReplacementTest, AmbigousPointer) {
const std::string text = R"(
; CHECK: [[s1:%\w+]] = OpTypeStruct %uint
; CHECK: [[s2:%\w+]] = OpTypeStruct %uint
; CHECK: [[s3:%\w+]] = OpTypeStruct [[s2]]
; CHECK: [[s3_const:%\w+]] = OpConstantComposite [[s3]]
; CHECK: [[s2_ptr:%\w+]] = OpTypePointer Function [[s2]]
; CHECK: OpCompositeExtract [[s2]] [[s3_const]]
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
OpExecutionMode %2 OriginUpperLeft
OpSource ESSL 310
%void = OpTypeVoid
%5 = OpTypeFunction %void
%uint = OpTypeInt 32 0
%_struct_7 = OpTypeStruct %uint
%_struct_8 = OpTypeStruct %uint
%_struct_9 = OpTypeStruct %_struct_8
%uint_1 = OpConstant %uint 1
%11 = OpConstantComposite %_struct_8 %uint_1
%12 = OpConstantComposite %_struct_9 %11
%_ptr_Function__struct_9 = OpTypePointer Function %_struct_9
%_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
%2 = OpFunction %void None %5
%15 = OpLabel
%var = OpVariable %_ptr_Function__struct_9 Function
OpStore %var %12
%ld = OpLoad %_struct_9 %var
%ex = OpCompositeExtract %_struct_8 %ld 0
OpReturn
OpFunctionEnd
)";
SinglePassRunAndMatch<ScalarReplacementPass>(text, true);
}
} // namespace
} // namespace opt
} // namespace spvtools