Skip to content

SPIR-V: copy late bool phi values (NVIDIA 580 crash in Astro's Playroom) - #49

Closed
pernahlebihtampan wants to merge 1 commit into
Jetsku:mainfrom
pernahlebihtampan:fix/nvidia-bool-phi-crash
Closed

pernahlebihtampan wants to merge 1 commit into
Jetsku:mainfrom
pernahlebihtampan:fix/nvidia-bool-phi-crash

Conversation

@pernahlebihtampan

Copy link
Copy Markdown
Contributor

Problem

On Linux with an RTX 3070 and NVIDIA driver 580.178.04, Astro's Playroom (PPSA01325) closes right after the game leaves its menu:

Unhandled host exception: type=1 code=11 pc=0x00007c2a54557c88 (no module (guest or generated code)) access=1 address=0x0000000000000028

The faulting PC is inside NVIDIA's SPIR-V compiler, at libnvidia-glvkspirv.so.580.178.04+0x157c88. It fires while a background thread builds the software RT pipeline of compute shader 0x1a33cd8c1711bfb3. On Linux, CallCatchingStructuredException does not catch faults, so the emulator exits. (On Windows the same fault would turn software RT off for the session.)

Cause

From the driver disassembly: when the compiler translates a bool OpPhi whose incoming values are all defined before the phi (instruction results, not constants), it retypes the phi. It then inserts a conversion before the terminator of each predecessor. If a predecessor appears later in the function (a loop header's back edge), that block has not been translated yet, so getTerminator() returns null and the compiler dereferences it.

A 30-line hand-written compute shader reproduces this in a standalone Vulkan program: a loop header with OpPhi %bool %c0 %entry %c0 %continue, where %c0 is an OpULessThan in the entry block. It crashes at the same address. With a constant on one edge, or with the back-edge value defined in the continue block, it builds.

In the dumped module of kernel 0x1a33cd8c1711bfb3, five bool phis match this pattern.

Fix

EmitStructuredFunction now finds the incoming edges of bool phis whose predecessor is emitted at or after the phi's own block. On each such edge, it emits an OpCopyObject of the value at the end of the predecessor, before the terminator, and the phi takes the copy. The driver has not seen the copy yet when it reaches the phi, so it keeps the phi a plain bool. The phi's semantics do not change, and other phis are untouched.

Testing

  • Astro's Playroom on the RTX 3070 / 580.178.04 machine, driven past the menu by a virtual pad tapping Cross every 2 s. The run lasted 8 minutes in gameplay with no crash. All 13 RT kernels built, including 0x1a33cd8c1711bfb3 (1243 ms) and 0x7d6ab87e6c984bb7 (5705 ms).
  • All dumped RT modules (KYTY_RT_DUMP_DIR, function and .inline variants) pass spirv-val --target-env vulkan1.3. A script that looks for the crash pattern finds 0 matches.
  • I rebuilt the pre-fix module of 0x1a33cd8c1711bfb3 by stripping the copies. In the standalone harness it crashes at +0x157c88, while the fixed module gets past that point.
  • Not run: the unit tests (shader_recompiler_compute_tests, etc.). Not tested: AMD/Intel, or other NVIDIA driver versions.

The codegen version changes, so program caches rebuild, and the first build of each RT kernel takes a few seconds while the driver cache refills.

🤖 Generated with Claude Code

NVIDIA's SPIR-V compiler (driver 580.178, libnvidia-glvkspirv.so+0x157c88) dereferences a null
terminator on a bool OpPhi whose incoming values are all defined before it when one predecessor
comes later in the function (a loop header's back edge). Astro's Playroom's ray-traced lighting
kernel 0x1a33cd8c1711bfb3 has five such phis; the emulator closed right after the game left its
menu. On those edges the phi now takes a copy made at the end of the later predecessor, which the
driver has not seen yet at the phi, so the phi stays a plain bool.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Jetsku added a commit that referenced this pull request Oct 20, 2026
…into gtapipe

Co-Authored-By: Jetsku <59046009+Jetsku@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Jetsku

Jetsku commented Oct 24, 2026

Copy link
Copy Markdown
Owner

Has been merged and added to a release

@Jetsku Jetsku closed this Oct 24, 2026
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.

2 participants