spirv-reader: ignore phi inputs coming from non-ordered blocks

Bug: tint:804
Change-Id: I789c05a31d869052036351b8c173ef8cd7191cc2
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/52841
Auto-Submit: David Neto <dneto@google.com>
Commit-Queue: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
David Neto 2021-06-01 18:52:01 +00:00 committed by Tint LUCI CQ
parent 0895c238e3
commit ae5437cc87
3 changed files with 86 additions and 1 deletions

View File

@ -4362,7 +4362,7 @@ void FunctionEmitter::FindValuesNeedingNamedOrHoistedDefinition() {
auto* pred_block_info = GetBlockInfo(pred_block_id); auto* pred_block_info = GetBlockInfo(pred_block_id);
// The predecessor might not be in the block order at all, so we // The predecessor might not be in the block order at all, so we
// need this guard. // need this guard.
if (pred_block_info) { if (IsInBlockOrder(pred_block_info)) {
// Record the assignment that needs to occur at the end // Record the assignment that needs to occur at the end
// of the predecessor block. // of the predecessor block.
pred_block_info->phi_assignments.push_back({phi_id, value_id}); pred_block_info->phi_assignments.push_back({phi_id, value_id});

View File

@ -766,6 +766,13 @@ class FunctionEmitter {
return where->second.get(); return where->second.get();
} }
/// Is the block, represented by info, in the structured block order?
/// @param info the block
/// @returns true if the block is in the structured block order.
bool IsInBlockOrder(const BlockInfo* info) const {
return info && info->pos != kInvalidBlockPos;
}
/// Gets the local definition info for a result ID. /// Gets the local definition info for a result ID.
/// @param id the SPIR-V ID of local definition. /// @param id the SPIR-V ID of local definition.
/// @returns the definition info for the given ID, if it exists, or nullptr /// @returns the definition info for the given ID, if it exists, or nullptr

View File

@ -2234,6 +2234,84 @@ Return{}
EXPECT_EQ(expect, got); EXPECT_EQ(expect, got);
} }
TEST_F(SpvParserFunctionVarTest,
EmitStatement_Phi_ValueFromBlockNotInBlockOrderIgnored) {
// From crbug.com/tint/804
const auto assembly = Preamble() + R"(
%float_42 = OpConstant %float 42.0
%cond = OpUndef %bool
%100 = OpFunction %void None %voidfn
%10 = OpLabel
OpBranch %30
; unreachable
%20 = OpLabel
%499 = OpFAdd %float %float_42 %float_42
%500 = OpFAdd %float %499 %float_42
OpBranch %25
%25 = OpLabel
OpBranch %80
%30 = OpLabel
OpLoopMerge %90 %80 None
OpBranchConditional %cond %90 %40
%40 = OpLabel
OpBranch %90
%80 = OpLabel ; unreachable continue target
; but "dominated" by %20 and %25
%81 = OpPhi %float %500 %25
OpBranch %30 ; backedge
%90 = OpLabel
OpReturn
OpFunctionEnd
)";
auto p = parser(test::Assemble(assembly));
ASSERT_TRUE(p->BuildAndParseInternalModule()) << p->error() << assembly;
auto fe = p->function_emitter(100);
EXPECT_TRUE(fe.EmitBody()) << p->error();
const auto* expected = R"(Loop{
If{
(
ScalarConstructor[not set]{false}
)
{
Break{}
}
}
Break{}
continuing {
VariableDeclStatement{
Variable{
x_81_phi_1
none
__f32
}
}
VariableDeclStatement{
VariableConst{
x_81
none
__f32
{
Identifier[not set]{x_81_phi_1}
}
}
}
}
}
Return{}
)";
const auto got = ToString(p->builder(), fe.ast_body());
EXPECT_EQ(got, expected);
}
} // namespace } // namespace
} // namespace spirv } // namespace spirv
} // namespace reader } // namespace reader