Handle no index access chain in local access chain convert (#3678)

* Handle no index access chain in local access chain convert

Fixes #3643
This commit is contained in:
Steven Perron 2020-08-10 22:03:02 -04:00 committed by GitHub
parent bdeeae78a9
commit 8e1380996d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 2 deletions

View File

@ -77,6 +77,15 @@ void LocalAccessChainConvertPass::AppendConstantOperands(
bool LocalAccessChainConvertPass::ReplaceAccessChainLoad(
const Instruction* address_inst, Instruction* original_load) {
// Build and append load of variable in ptrInst
if (address_inst->NumInOperands() == 1) {
// An access chain with no indices is essentially a copy. All that is
// needed is to propagate the address.
context()->ReplaceAllUsesWith(
address_inst->result_id(),
address_inst->GetSingleWordInOperand(kAccessChainPtrIdInIdx));
return true;
}
std::vector<std::unique_ptr<Instruction>> new_inst;
uint32_t varId;
uint32_t varPteTypeId;
@ -109,6 +118,18 @@ bool LocalAccessChainConvertPass::ReplaceAccessChainLoad(
bool LocalAccessChainConvertPass::GenAccessChainStoreReplacement(
const Instruction* ptrInst, uint32_t valId,
std::vector<std::unique_ptr<Instruction>>* newInsts) {
if (ptrInst->NumInOperands() == 1) {
// An access chain with no indices is essentially a copy. However, we still
// have to create a new store because the old ones will be deleted.
BuildAndAppendInst(
SpvOpStore, 0, 0,
{{spv_operand_type_t::SPV_OPERAND_TYPE_ID,
{ptrInst->GetSingleWordInOperand(kAccessChainPtrIdInIdx)}},
{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {valId}}},
newInsts);
return true;
}
// Build and append load of variable in ptrInst
uint32_t varId;
uint32_t varPteTypeId;
@ -246,11 +267,13 @@ Pass::Status LocalAccessChainConvertPass::ConvertLocalAccessChains(
if (!GenAccessChainStoreReplacement(ptrInst, valId, &newInsts)) {
return Status::Failure;
}
size_t num_of_instructions_to_skip = newInsts.size() - 1;
dead_instructions.push_back(&*ii);
++ii;
ii = ii.InsertBefore(std::move(newInsts));
++ii;
++ii;
for (size_t i = 0; i < num_of_instructions_to_skip; ++i) {
++ii;
}
modified = true;
} break;
default:

View File

@ -927,6 +927,37 @@ TEST_F(LocalAccessChainConvertTest, IdOverflowReplacingStore2) {
EXPECT_EQ(Pass::Status::Failure, std::get<1>(result));
}
TEST_F(LocalAccessChainConvertTest, AccessChainWithNoIndex) {
const std::string before =
R"(
; CHECK: OpFunction
; CHECK: [[var:%\w+]] = OpVariable
; CHECK: OpStore [[var]] %true
; CHECK: OpLoad %bool [[var]]
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
OpExecutionMode %2 OriginUpperLeft
OpSource ESSL 310
%void = OpTypeVoid
%4 = OpTypeFunction %void
%bool = OpTypeBool
%true = OpConstantTrue %bool
%_ptr_Function_bool = OpTypePointer Function %bool
%2 = OpFunction %void None %4
%8 = OpLabel
%9 = OpVariable %_ptr_Function_bool Function
%10 = OpAccessChain %_ptr_Function_bool %9
OpStore %10 %true
%11 = OpLoad %bool %10
OpReturn
OpFunctionEnd
)";
SinglePassRunAndMatch<LocalAccessChainConvertPass>(before, true);
}
// TODO(greg-lunarg): Add tests to verify handling of these cases:
//
// Assorted vector and matrix types