SPU: More UB fixes

This commit is contained in:
Elad 2026-05-14 13:21:23 +03:00 committed by GitHub
parent c860aa2107
commit 53d76db753
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 20 additions and 16 deletions

View File

@ -1222,7 +1222,7 @@ void spu_cache::initialize(bool build_existing_cache)
}
// Initialize global cache instance
if (g_cfg.core.spu_cache && cache)
if (g_cfg.core.spu_cache && !spu_precompilation_enabled && cache)
{
g_fxo->get<spu_cache>() = std::move(cache);
}
@ -1282,8 +1282,8 @@ spu_runtime::spu_runtime()
fs::remove_all(m_cache_path + "llvm/", false);
}
fs::file(m_cache_path + "spu.log", fs::rewrite);
fs::file(m_cache_path + "spu-ir.log", fs::rewrite);
fs::write_file(m_cache_path + "spu.log", fs::rewrite);
fs::write_file(m_cache_path + "spu-ir.log", fs::rewrite);
}
}
@ -3215,10 +3215,13 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
jt_abs.clear();
}
// If this fails, this is a TODO to compare them in another way
ensure(jt_abs.size() != jt_rel.size());
}
if (jt_abs.size() >= jt_rel.size())
const bool abs_domainates = jt_abs.size() > jt_rel.size();
if (abs_domainates)
{
const u32 new_size = (start - lsa) / 4 + ::size32(jt_abs);
@ -3236,8 +3239,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
m_targets.emplace(pos, std::move(jt_abs));
}
if (jt_rel.size() >= jt_abs.size())
else
{
const u32 new_size = (start - lsa) / 4 + ::size32(jt_rel);
@ -8766,6 +8768,8 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
void spu_recompiler_base::dump(const spu_program& result, std::string& out, u32 block_min, u32 block_max)
{
block_max = std::min<u32>(block_max, SPU_LS_SIZE);
SPUDisAsm dis_asm(cpu_disasm_mode::dump, reinterpret_cast<const u8*>(result.data.data()), result.lower_bound);
std::string hash;

View File

@ -2637,7 +2637,7 @@ public:
for (u32 iteration_emit = 0; is_reduced_loop; m_pos += 4)
{
if (m_pos != baddr && m_block_info[m_pos / 4] && m_reduced_loop_info->loop_end < m_pos)
if (m_pos != baddr && m_pos != SPU_LS_SIZE && m_block_info[m_pos / 4] && m_reduced_loop_info->loop_end < m_pos)
{
fmt::throw_exception("LLVM: Reduced Loop Pattern: Exit(1) too early at 0x%x", m_pos);
}
@ -3217,7 +3217,7 @@ public:
for (u32 target : m_bbs[cur].targets)
{
if (!m_block_info[target / 4])
if (target == SPU_LS_SIZE || !m_block_info[target / 4])
{
continue;
}
@ -9066,7 +9066,7 @@ public:
for (u32 target : tfound->second)
{
if (m_block_info[target / 4])
if (target != SPU_LS_SIZE && m_block_info[target / 4])
{
targets.emplace(target, nullptr);
}

View File

@ -714,14 +714,14 @@ protected:
u64 m_hash_start;
// Bit indicating start of the block
std::bitset<0x10000> m_block_info;
std::bitset<SPU_LS_SIZE / 4> m_block_info;
// GPR modified by the instruction (-1 = not set)
std::array<u8, 0x10000> m_regmod;
std::array<u8, SPU_LS_SIZE / 4> m_regmod;
std::bitset<0x10000> m_use_ra;
std::bitset<0x10000> m_use_rb;
std::bitset<0x10000> m_use_rc;
std::bitset<SPU_LS_SIZE / 4> m_use_ra;
std::bitset<SPU_LS_SIZE / 4> m_use_rb;
std::bitset<SPU_LS_SIZE / 4> m_use_rc;
// List of possible targets for the instruction (entry shouldn't exist for simple instructions)
std::unordered_map<u32, std::vector<u32>, value_hash<u32, 2>> m_targets;
@ -730,10 +730,10 @@ protected:
std::unordered_map<u32, std::vector<u32>, value_hash<u32, 2>> m_preds;
// List of function entry points and return points (set after BRSL, BRASL, BISL, BISLED)
std::bitset<0x10000> m_entry_info;
std::bitset<SPU_LS_SIZE / 4> m_entry_info;
// Set after return points and disjoint chunks
std::bitset<0x10000> m_ret_info;
std::bitset<SPU_LS_SIZE / 4> m_ret_info;
// Basic block information
struct block_info