fix cond with else that is empty bug (#470)

This commit is contained in:
water111 2021-05-12 15:54:33 -04:00 committed by GitHub
parent 223adeeb0c
commit 8d4b644a14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 20 additions and 10 deletions

View File

@ -43,7 +43,7 @@ InstructionParser::InstructionParser() {
InstructionKind::BGTZ, InstructionKind::BLTZL, InstructionKind::BGTZL,
InstructionKind::BGEZL, InstructionKind::MTC1, InstructionKind::MFC1,
InstructionKind::MFLO, InstructionKind::MFHI, InstructionKind::MTLO1,
InstructionKind::MFLO1, InstructionKind::SYNCL}) {
InstructionKind::MFLO1, InstructionKind::SYNCL, InstructionKind::PCPYUD}) {
auto& info = gOpcodeInfo[int(i)];
if (info.defined) {
m_opcode_name_lookup[info.name] = int(i);

View File

@ -1248,7 +1248,7 @@ bool ControlFlowGraph::find_cond_w_empty_else() {
return true;
}
// printf("cwe try %s %s\n", c0->to_string().c_str(), b0->to_string().c_str());
// printf("cwe try %s %s\n", c0->to_string().c_str(), b0->to_string().c_str());
// first condition should have the _option_ to fall through to first body
if (c0->succ_ft != b0 || c0->end_branch.kind != CfgVtx::DelaySlotKind::NOP) {
@ -1290,11 +1290,10 @@ bool ControlFlowGraph::find_cond_w_empty_else() {
else_block = end_block;
}
if (else_block->succ_branch) {
return true;
}
assert(!else_block->end_branch.has_branch);
// the else code is empty, so the else block is the same as the end block.
// in this empty else case, we don't care what the "else" block end conditions are.
// else must fall through to end with no possible branch.
// it's not our problem to deal with the end block's branching.;
std::vector<CondWithElse::Entry> entries = {{c0, b0}};
auto* prev_condition = c0;

View File

@ -109,6 +109,7 @@ class Function {
std::vector<Instruction> instructions;
std::vector<BasicBlock> basic_blocks;
std::shared_ptr<ControlFlowGraph> cfg = nullptr;
bool cfg_ok = false;
int prologue_start = -1;
int prologue_end = -1;

View File

@ -211,6 +211,8 @@ void ObjectFileDB::ir2_basic_block_pass() {
lg::warn("Function {} from {} failed to build control flow graph!",
func.guessed_name.to_string(), data.to_unique_name());
failed_to_build_cfg++;
} else {
func.cfg_ok = true;
}
}
@ -237,6 +239,9 @@ void ObjectFileDB::ir2_stack_spill_slot_pass() {
int functions_with_spills = 0;
int total_slots = 0;
for_each_function_def_order([&](Function& func, int, ObjectFileData&) {
if (!func.cfg_ok) {
return;
}
auto spill_map = build_spill_map(func.instructions, {func.prologue_end, func.epilogue_start});
auto map_size = spill_map.size();
if (map_size) {
@ -259,6 +264,9 @@ void ObjectFileDB::ir2_atomic_op_pass(const Config& config) {
int attempted = 0;
int successful = 0;
for_each_function_def_order([&](Function& func, int segment_id, ObjectFileData& data) {
if (!func.cfg_ok) {
return;
}
(void)segment_id;
total_functions++;
if (!func.suspected_asm) {

View File

@ -153,6 +153,8 @@ std::unique_ptr<FormRegressionTest::TestData> FormRegressionTest::make_function(
EXPECT_TRUE(test->func.cfg->is_fully_resolved());
if (!test->func.cfg->is_fully_resolved()) {
fmt::print("CFG:\n{}\n", test->func.cfg->to_dot());
} else {
test->func.cfg_ok = true;
}
// find stack spill slots

View File

@ -123,7 +123,7 @@ TEST_F(FormRegressionTest, Min) {
std::string func =
" sll r0, r0, 0\n"
" or v0, a0, r0\n"
" or v1, a1, r0 \n"
" or v1, a1, r0\n"
" slt a0, v0, v1\n"
" movz v0, v1, a0\n"
" jr ra\n"
@ -179,7 +179,7 @@ TEST_F(FormRegressionTest, FormatString) {
" jalr ra, t9\n"
" sll v0, ra, 0\n"
" or v0, gp, r0 \n"
" or v0, gp, r0\n"
" ld ra, 0(sp)\n"
" ld fp, 8(sp)\n"
" lq gp, 16(sp)\n"
@ -880,4 +880,4 @@ TEST_F(FormRegressionTest, TypeOf) {
" (ret-value v0-0)\n"
" )";
test_no_expr(func, type, expected, false);
}
}