mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-12-25 17:21:06 +00:00
Get KillNameAndDecorates to handle group decorations. (#1919)
It seems like the current implementation of KillNameAndDecorates does not handle group decorations correctly. The id being removed is not removed from the OpGroupDecorate instructions. Even worst, any decorations that apply to that group are removed. The solution is to use the function in the decoration manager that will remove the decorations and update the instructions instead of doing the work itself.
This commit is contained in:
parent
90a12b3d4d
commit
b85fb4a300
@ -107,9 +107,6 @@ Instruction* IRContext::KillInst(Instruction* inst) {
|
||||
instr_to_block_.erase(inst);
|
||||
}
|
||||
if (AreAnalysesValid(kAnalysisDecorations)) {
|
||||
if (inst->result_id() != 0) {
|
||||
decoration_mgr_->RemoveDecorationsFrom(inst->result_id());
|
||||
}
|
||||
if (inst->IsDecoration()) {
|
||||
decoration_mgr_->RemoveDecoration(inst);
|
||||
}
|
||||
@ -258,12 +255,8 @@ void IRContext::AnalyzeUses(Instruction* inst) {
|
||||
}
|
||||
|
||||
void IRContext::KillNamesAndDecorates(uint32_t id) {
|
||||
std::vector<Instruction*> decorations =
|
||||
get_decoration_mgr()->GetDecorationsFor(id, true);
|
||||
|
||||
for (Instruction* inst : decorations) {
|
||||
KillInst(inst);
|
||||
}
|
||||
analysis::DecorationManager* dec_mgr = get_decoration_mgr();
|
||||
dec_mgr->RemoveDecorationsFrom(id);
|
||||
|
||||
std::vector<Instruction*> name_to_kill;
|
||||
for (auto name : GetNames(id)) {
|
||||
|
@ -217,6 +217,64 @@ TEST_F(IRContextTest, KillMemberName) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(IRContextTest, KillGroupDecoration) {
|
||||
const std::string text = R"(
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %2 "main"
|
||||
OpExecutionMode %2 OriginUpperLeft
|
||||
OpSource GLSL 430
|
||||
OpDecorate %3 Restrict
|
||||
%3 = OpDecorationGroup
|
||||
OpGroupDecorate %3 %4 %5
|
||||
%6 = OpTypeFloat 32
|
||||
%7 = OpTypePointer Function %6
|
||||
%8 = OpTypeStruct %6
|
||||
%9 = OpTypeVoid
|
||||
%10 = OpTypeFunction %9
|
||||
%2 = OpFunction %9 None %10
|
||||
%11 = OpLabel
|
||||
%4 = OpVariable %7 Function
|
||||
%5 = OpVariable %7 Function
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
std::unique_ptr<IRContext> context =
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
|
||||
|
||||
// Build the decoration manager.
|
||||
context->get_decoration_mgr();
|
||||
|
||||
// Delete the second variable.
|
||||
context->KillDef(5);
|
||||
|
||||
// The three decorations instructions should still be there. The first two
|
||||
// should be the same, but the third should have %5 removed.
|
||||
|
||||
// Check the OpDecorate instruction
|
||||
auto inst = context->annotation_begin();
|
||||
EXPECT_EQ(inst->opcode(), SpvOpDecorate);
|
||||
EXPECT_EQ(inst->GetSingleWordInOperand(0), 3);
|
||||
|
||||
// Check the OpDecorationGroup Instruction
|
||||
++inst;
|
||||
EXPECT_EQ(inst->opcode(), SpvOpDecorationGroup);
|
||||
EXPECT_EQ(inst->result_id(), 3);
|
||||
|
||||
// Check that %5 is no longer part of the group.
|
||||
++inst;
|
||||
EXPECT_EQ(inst->opcode(), SpvOpGroupDecorate);
|
||||
EXPECT_EQ(inst->NumInOperands(), 2);
|
||||
EXPECT_EQ(inst->GetSingleWordInOperand(0), 3);
|
||||
EXPECT_EQ(inst->GetSingleWordInOperand(1), 4);
|
||||
|
||||
// Check that we are at the end.
|
||||
++inst;
|
||||
EXPECT_EQ(inst, context->annotation_end());
|
||||
}
|
||||
|
||||
TEST_F(IRContextTest, TakeNextUniqueIdIncrementing) {
|
||||
const uint32_t NUM_TESTS = 1000;
|
||||
IRContext localContext(SPV_ENV_UNIVERSAL_1_2, nullptr);
|
||||
|
Loading…
Reference in New Issue
Block a user