SPU: Verify SPU Reduced loop completability

This commit is contained in:
Elad 2026-04-01 09:27:51 +03:00
parent f63b1b5dc1
commit a03a78dbd2
2 changed files with 24 additions and 2 deletions

View file

@ -6731,6 +6731,13 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
break;
}
if (reg_index != i && ::at32(reg->regs, reg_index))
{
// Unimplemented
break_reduced_loop_pattern(30, reduced_loop->discard());
break;
}
u32 cond_val_incr = static_cast<s32>(reg_org->IMM);
if (reg_org->mod1_type == spu_itype::AI || reg_org->mod1_type == spu_itype::AHI)

View file

@ -2542,9 +2542,24 @@ public:
break;
}
}
}
//condition = m_ir->getInt1(0);
// TODO: Optimze so constant evalatuated cases will not be checked
const bool is_cond_need_runtime_verify = compare == ICmpInst::ICMP_NE && (!m_reduced_loop_info->cond_val_is_immediate || m_reduced_loop_info->cond_val_incr % 2 == 0);
if (is_cond_need_runtime_verify)
{
// Verify that it is actually possible to finish the loop and it is not an infinite loop
// First: create a mask of the bits that definitely do not change between iterations (0 results in umax which is accurate here)
const auto no_change_bits = m_ir->CreateAnd(m_ir->CreateNot(cond_val_incr), m_ir->CreateSub(cond_val_incr, m_ir->getIntN(type_bits, 1)));
// Compare that when the mask applied to both the result and the original value is the same
const auto cond_verify = m_ir->CreateICmpEQ(m_ir->CreateAnd(loop_dictator_after_adjustment, no_change_bits), m_ir->CreateAnd(loop_argument, no_change_bits));
// Amend condition
condition = m_ir->CreateAnd(cond_verify, condition);
}
}
m_ir->CreateCondBr(condition, optimization_block, block_optimization_next);
};