mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-12-16 04:09:07 +00:00
rsx/cfg: Fix edge case where an empty block is defined
This commit is contained in:
parent
0c455d12c9
commit
2b0456520e
@ -194,22 +194,45 @@ namespace rsx::assembler
|
||||
case RSX_FP_OPCODE_IFE:
|
||||
{
|
||||
// Inserts if and else and end blocks
|
||||
auto parent = bb;
|
||||
bb = safe_insert_block(parent, pc + 1, EdgeType::IF);
|
||||
if (src2.end_offset != src1.else_offset)
|
||||
const u32 end_addr = src2.end_offset >> 2u;
|
||||
const u32 else_addr = src1.else_offset >> 2u;
|
||||
if (end_addr == pc + 1u)
|
||||
{
|
||||
else_blocks.push_back(safe_insert_block(parent, src1.else_offset >> 2, EdgeType::ELSE));
|
||||
// NOP. Empty IF block
|
||||
bb->instructions.pop_back();
|
||||
break;
|
||||
}
|
||||
end_blocks.push_back(safe_insert_block(parent, src2.end_offset >> 2, EdgeType::ENDIF));
|
||||
|
||||
if (else_addr > end_addr)
|
||||
{
|
||||
// Our systems support this, but it is not verified on real hardware.
|
||||
rsx_log.error("CFG: Non-contiguous branch detected. Report to developers.");
|
||||
}
|
||||
|
||||
auto parent = bb;
|
||||
bb = safe_insert_block(parent, pc + 1u, EdgeType::IF);
|
||||
if (end_addr != else_addr)
|
||||
{
|
||||
else_blocks.push_back(safe_insert_block(parent, else_addr, EdgeType::ELSE));
|
||||
}
|
||||
end_blocks.push_back(safe_insert_block(parent, end_addr, EdgeType::ENDIF));
|
||||
break;
|
||||
}
|
||||
case RSX_FP_OPCODE_LOOP:
|
||||
case RSX_FP_OPCODE_REP:
|
||||
{
|
||||
// Inserts for and end blocks
|
||||
const u32 end_addr = src2.end_offset >> 2u;
|
||||
if (end_addr == pc + 1u)
|
||||
{
|
||||
// NOP. Empty LOOP block
|
||||
bb->instructions.pop_back();
|
||||
break;
|
||||
}
|
||||
|
||||
auto parent = bb;
|
||||
bb = safe_insert_block(parent, pc + 1, EdgeType::LOOP);
|
||||
end_blocks.push_back(safe_insert_block(parent, src2.end_offset >> 2, EdgeType::ENDLOOP));
|
||||
bb = safe_insert_block(parent, pc + 1u, EdgeType::LOOP);
|
||||
end_blocks.push_back(safe_insert_block(parent, end_addr, EdgeType::ENDLOOP));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@ -210,4 +210,22 @@ namespace rsx::assembler
|
||||
EXPECT_EQ(bb6->pred[1].from, bb3);
|
||||
EXPECT_EQ(bb6->pred[2].from, bb0);
|
||||
}
|
||||
|
||||
TEST(CFG, FpToCFG_EmptyIF)
|
||||
{
|
||||
auto ir = FPIR::from_source(
|
||||
"IF.LT;" // Empty branch
|
||||
"ENDIF;"
|
||||
"MOV R0, R1;" // False merge block.
|
||||
);
|
||||
|
||||
RSXFragmentProgram program{};
|
||||
auto bytecode = ir.compile();
|
||||
program.data = bytecode.data();
|
||||
|
||||
FlowGraph graph = deconstruct_fragment_program(program);
|
||||
|
||||
ASSERT_EQ(graph.blocks.size(), 1);
|
||||
EXPECT_EQ(graph.blocks.front().instructions.size(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user