mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-10-18 19:20:05 +00:00
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:
parent
bdeeae78a9
commit
8e1380996d
@ -77,6 +77,15 @@ void LocalAccessChainConvertPass::AppendConstantOperands(
|
|||||||
bool LocalAccessChainConvertPass::ReplaceAccessChainLoad(
|
bool LocalAccessChainConvertPass::ReplaceAccessChainLoad(
|
||||||
const Instruction* address_inst, Instruction* original_load) {
|
const Instruction* address_inst, Instruction* original_load) {
|
||||||
// Build and append load of variable in ptrInst
|
// 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;
|
std::vector<std::unique_ptr<Instruction>> new_inst;
|
||||||
uint32_t varId;
|
uint32_t varId;
|
||||||
uint32_t varPteTypeId;
|
uint32_t varPteTypeId;
|
||||||
@ -109,6 +118,18 @@ bool LocalAccessChainConvertPass::ReplaceAccessChainLoad(
|
|||||||
bool LocalAccessChainConvertPass::GenAccessChainStoreReplacement(
|
bool LocalAccessChainConvertPass::GenAccessChainStoreReplacement(
|
||||||
const Instruction* ptrInst, uint32_t valId,
|
const Instruction* ptrInst, uint32_t valId,
|
||||||
std::vector<std::unique_ptr<Instruction>>* newInsts) {
|
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
|
// Build and append load of variable in ptrInst
|
||||||
uint32_t varId;
|
uint32_t varId;
|
||||||
uint32_t varPteTypeId;
|
uint32_t varPteTypeId;
|
||||||
@ -246,11 +267,13 @@ Pass::Status LocalAccessChainConvertPass::ConvertLocalAccessChains(
|
|||||||
if (!GenAccessChainStoreReplacement(ptrInst, valId, &newInsts)) {
|
if (!GenAccessChainStoreReplacement(ptrInst, valId, &newInsts)) {
|
||||||
return Status::Failure;
|
return Status::Failure;
|
||||||
}
|
}
|
||||||
|
size_t num_of_instructions_to_skip = newInsts.size() - 1;
|
||||||
dead_instructions.push_back(&*ii);
|
dead_instructions.push_back(&*ii);
|
||||||
++ii;
|
++ii;
|
||||||
ii = ii.InsertBefore(std::move(newInsts));
|
ii = ii.InsertBefore(std::move(newInsts));
|
||||||
++ii;
|
for (size_t i = 0; i < num_of_instructions_to_skip; ++i) {
|
||||||
++ii;
|
++ii;
|
||||||
|
}
|
||||||
modified = true;
|
modified = true;
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
|
@ -927,6 +927,37 @@ TEST_F(LocalAccessChainConvertTest, IdOverflowReplacingStore2) {
|
|||||||
EXPECT_EQ(Pass::Status::Failure, std::get<1>(result));
|
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:
|
// TODO(greg-lunarg): Add tests to verify handling of these cases:
|
||||||
//
|
//
|
||||||
// Assorted vector and matrix types
|
// Assorted vector and matrix types
|
||||||
|
Loading…
Reference in New Issue
Block a user