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:
parent
0895c238e3
commit
ae5437cc87
|
@ -4362,7 +4362,7 @@ void FunctionEmitter::FindValuesNeedingNamedOrHoistedDefinition() {
|
|||
auto* pred_block_info = GetBlockInfo(pred_block_id);
|
||||
// The predecessor might not be in the block order at all, so we
|
||||
// need this guard.
|
||||
if (pred_block_info) {
|
||||
if (IsInBlockOrder(pred_block_info)) {
|
||||
// Record the assignment that needs to occur at the end
|
||||
// of the predecessor block.
|
||||
pred_block_info->phi_assignments.push_back({phi_id, value_id});
|
||||
|
|
|
@ -766,6 +766,13 @@ class FunctionEmitter {
|
|||
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.
|
||||
/// @param id the SPIR-V ID of local definition.
|
||||
/// @returns the definition info for the given ID, if it exists, or nullptr
|
||||
|
|
|
@ -2234,6 +2234,84 @@ Return{}
|
|||
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 spirv
|
||||
} // namespace reader
|
||||
|
|
Loading…
Reference in New Issue