Skip to content

SPU Analyzer: Giga Block Crash Fix for Skylanders Giants - #18935

Merged
elad335 merged 2 commits into
RPCS3:masterfrom
chotchki:spu-analyser-guard-stop-trap
Jun 23, 2026
Merged

elad335 merged 2 commits into
RPCS3:masterfrom
chotchki:spu-analyser-guard-stop-trap

Conversation

@chotchki

@chotchki chotchki commented Jun 22, 2026 •

Copy link
Copy Markdown
Contributor

When running Skylanders Giants with SPU LLVM, the game crashes. I used Claude to isolate down to a minimal fix and test case. Post fix the title launches correctly.

In giga block mode, a brsl whose return address holds a stop (0x0) word gets a return-point block during discovery that the cleanup pass then deletes (its result.data word is 0) without dropping the m_targets edge pointing at it. The reg-state walk follows that dangling edge into initiate_patterns, where ::at32(m_bbs, bpc) range-check-fails and freezes the SPU thread (reproduced on Skylanders Giants, giga + SPU LLVM).

Guard the lookup the same way get_block_targets/get_block_preds already do.

Add tests/test_spu_analyser.cpp: a claude-written SPU program that reproduces the crash on the unpatched analyser.

@elad335 elad335 changed the title MacOS Giga Block Crash Fix for Skylanders Giants SPU Analyzer: Giga Block Crash Fix for Skylanders Giants Jun 23, 2026
@elad335
elad335 enabled auto-merge (squash) June 23, 2026 00:25
@elad335
elad335 disabled auto-merge June 23, 2026 00:27

@elad335 elad335 left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fix is incomplete, you need to remove the dead targets from m_targets

@digant73

Copy link
Copy Markdown
Contributor

maybe the test file needs to be added also in rpcs3_test.vcxproj

chotchki and others added 2 commits June 23, 2026 13:18
Giga cleanup clears m_block_info for removed blocks but left their in-range edges in m_targets, so the register-state walk dereferenced a stale target and aborted ("Range check failed") - e.g. a brsl whose return is a stop-trap, hit in Skylanders Giants. Prune those edges at the m_targets cleanup; export out_target_list after the prune so callers see the cleaned map; keep the initiate_patterns and cond_next-walk guards as defense in depth.

Adds made-up-data regression tests (the exported-map test fails without the prune) and the rpcs3_test.vcxproj entry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The "Fill more block info" re-decode indexed result.data[(ia - lsa) / 41] instead of / 4 (its companion decode uses / 4), so it read the wrong word and corrupted the per-block reg_const / reg_val32 constant propagation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@chotchki
chotchki force-pushed the spu-analyser-guard-stop-trap branch from 10d8141 to 4e73b55 Compare June 23, 2026 21:21
@chotchki

Copy link
Copy Markdown
Contributor Author

So I had originally kept the fix very narrow since based on how the other guards worked I didn't think pruning was right. This set of commits fixes that. I also had Claude scan across the SPUCommonRecompiler.cpp‎ for any other range violations and it also found a typo. I've had it implement tests for all the changes and picked up @digant73's note about the CMake vs Visual Studio project miss (I don't have a Windows box handy so I'm hoping CI catches any errors on that edit).

  • Prune the dead targets from m_targets (the core ask): the cleanup pass now also drops in-range target edges whose block was removed (|| !m_block_info[*it2/4]), so the dangling edges never reach m_bbs — not just guarded against downstream.
  • out_target_list is now exported after the prune — it ran before, so the exported map still leaked the dead edges.
  • Kept the initiate_patterns guard and added a matching one in the cond_next loop-body walk as defense-in-depth (the existing get_block_targets/get_block_preds guards stay too).
  • Also fixed a pre-existing /41 → /4 index typo in the Giga "Fill more block info" re-decode — it read the wrong word and corrupted per-block reg_const/reg_val32. It's a separate commit; happy to pull it into its own PR if you'd prefer.
  • Added test_spu_analyser.cpp to rpcs3_test.vcxproj — thanks @digant73.

Tests: the original stop-trap regression plus three more. The exported-map test is discriminating (fails without the prune); the loop-body-walk and re-decode tests are positive coverage (the /41 effect is internal-only, so it can't be pinned through analyse()'s public output). All four pass locally via rpcs3_test; every SPU word is made-up data.

@elad335
elad335 enabled auto-merge (rebase) June 23, 2026 22:23
@elad335
elad335 merged commit 42242b3 into RPCS3:master Jun 23, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants