From bd687b41d32331662356c3d43f2d66559ea56d3b Mon Sep 17 00:00:00 2001 From: Eladash <18193363+elad335@users.noreply.github.com> Date: Thu, 28 Dec 2023 21:14:58 +0200 Subject: [PATCH] SPU LLVM: Fix savestates with LLVM Sneaky bug: allow invalidation from blocks that do not contain a store but do a gpr-state critical operation. --- rpcs3/Emu/Cell/SPURecompiler.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/rpcs3/Emu/Cell/SPURecompiler.cpp b/rpcs3/Emu/Cell/SPURecompiler.cpp index 6546885b8a..d4aa77aca1 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.cpp +++ b/rpcs3/Emu/Cell/SPURecompiler.cpp @@ -6080,7 +6080,7 @@ public: llvm::SetVector work_list; std::unordered_map worked_on; - if (std::count(killers.begin(), killers.end(), common_pdom) == 0) + if (!common_pdom || std::count(killers.begin(), killers.end(), common_pdom) == 0) { if (common_pdom) { @@ -6099,6 +6099,7 @@ public: } } + // bool flag indicates the presence of a memory barrier before the killer store std::vector> work2_list; for (usz wi = 0; wi < work_list.size(); wi++) @@ -6137,6 +6138,9 @@ public: worked_on[work2_list[wi].first] = true; } + // Need to treat tails differently: do not require checking barrier (checked before in a suitable manner) + const usz work_list_tail_blocks_max_index = work2_list.size(); + for (usz wi = 0; wi < work2_list.size(); wi++) { auto [cur, found_user] = work2_list[wi]; @@ -6153,9 +6157,15 @@ public: continue; } - if (!found_user && bb_to_info[cur] && bb_to_info[cur]->store_context_last_id[i]) + if (!found_user && wi >= work_list_tail_blocks_max_index) { - found_user = true; + if (auto info = bb_to_info[cur]) + { + if (info->store_context_ctr[i] != 1) + { + found_user = true; + } + } } for (auto* p : llvm::predecessors(cur))