Repository navigation
perf(shader): fold masks, shifts and field extracts through bits they do not use - #7673
Conversation
… do not use The constant folder now knows which bits a value can hold (masks, merges, shifts, field extracts, 16- and 8-bit widenings, selects) and which bits a user reads: - a mask that clears no bit the value can hold is dropped, and so is a merged part with no bit under the mask; - And(And(x, a), m) becomes And(x, m) when m keeps no bit outside a, and a mask rewrite is folded again; - a field extract, shift, mask or 16-bit truncation reads through masks that keep the bits it reads and through merged parts that hold none; - a right shift of a left shift by the same amount becomes a mask; - BitFieldUExtract(x, 0, n) is x when x has no bit at or above n; - Or of two masked parts of one word becomes the word under the union of the masks (the word itself when they cover it); - a field extract of a left shift reads the unshifted word. These patterns come from 16-bit halves of 32-bit registers (f16 and packed math), which the translator splits and merges per instruction. Test: agc_constant_bit_test gets six cases (repeated, narrower and wider masks, a mask under a merge, half extractions, halves that rejoin); all six fail on main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XBXM4pgkMHYEtqN1EQni2P
|
This pull request is labeled |
|
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
|
AMD run, since the description covers an RTX 4090. Radeon 860M (RDNA 3.5, driver 32.0.13058.8001), Windows 11 26300, WinLibs GCC 15.2.0 r7, Release,
AI-assisted |
|
About the performance-report request: I captured the requested warm-cache traces (GTA V PPSA04264, open world, RTX 4090). Two things make them a poor fit for this change:
This change only makes modules smaller. Its effect is on pipeline creation, so I measured that directly: cold NVIDIA AI-assisted (Claude Code). |
|
Intel and AMD Windows data: Windows 11 Pro 26300, WinLibs GCC 15.2.0 r7, Release, every execution test built,
This is a correctness check only; I measured no speed. I also ran full CTest with this PR and the 13 other open AGC and shader PRs I tested in the same batch merged together (#7668, #7659, #7504, #7432, #7426, #7413, #7480, #7465, #7466, #7464, #7449, #7489, #7560). Neither GPU showed a failure beyond AI-assisted: yes (Claude Code) |
|
Thank you @savvaniss: RDNA4 (RX 9070 XT) and the UHD 770 both fail on AI-assisted: yes (Claude Code) |
|
Checked the demanded-bits rewrites (and/or/xor merges, shifts, field extracts, 16-bit truncation, SRL(SLL) and masked-part merging) against the IR semantics: each keeps every bit its user reads. The six new |
#7018 reads the low-half factors of v_mul_lo_u16 and v_pk_mul_lo_u16 as 24-bit fields because AMD's Windows driver stores the full 32-bit product when it knows both factors fit in 16 bits. #7673's fold of BitFieldUExtract(x, 0, n) into x removed those reads when the program had masked the factors to 16 bits, so agc_driver_mul_lo_u16_high_half failed again on that driver. The folder now keeps a field read that a multiply uses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
What
The translator splits and merges the 16-bit halves of 32-bit registers on every f16 or packed instruction. As a result, the IR carries many masks, shifts and field extracts that do not change any bit their user reads. This change teaches the constant folder which bits a value can hold (masks, merges, shifts, field extracts, 16- and 8-bit widenings, selects) and which bits a user reads. It applies these exact rewrites:
And(And(x, a), m)becomesAnd(x, m)whenmkeeps no bit outsidea. A rewritten mask is folded again:Foldvisits each instruction once, so chains used to survive.ShiftRightLogical(ShiftLeftLogical(x, k), k)becomesAnd(x, ~0u >> k).BitFieldUExtract(x, 0, n)isxwhenxhas no bit at or aboven.Orof two masked parts of one word becomes that word under the union of the masks, or the word itself when the masks cover it.Every rewrite gives the same bits, so shader results do not change.
Tested
Windows 11, MinGW GCC 15.2, RTX 4090 (616.92):
agc_constant_bit_testgets six new cases: repeated, narrower and wider masks, a mask under a merge, half extractions, halves that rejoin. All six fail onmain.ctest -R ^agc_: 726/727. The failure isagc_driver_bda_device, which fails onmaintoo.Size and compile time, GTA V (PPSA04264) compute shaders dumped with
APS5_DUMP_SHADERS:agc_shader_replay)How the compile times were measured:
APS5_DUMP_COMPUTE_PIPELINESthrough the driver's dispatch path.agc_compute_pipeline_replay.pipeline_createis the median of 3 replays, each with a distinctOpSourceExtensionso that the NVIDIA driver cache misses.Output check: the same rewrites were run on a local test branch, where 71 of these compute shaders were dispatched on synthetic memory with and without them. Every byte they wrote was identical on the RTX 4090.
Not attached: frame traces. This changes pipeline creation time (stutter while shaders compile), not the steady-state frame.
Performance capture
GTA V (PPSA04264), open world from the same save, RTX 4090, one run each, same session. Base =
main47a266c + #6488 + #6848 + a local bench aid (keyboard pad input while an IME session is open), because GTA V does not run on plainmain;cdeb62157e5eis this PR on top of it. Traces: fork release perf-7673-7677-20261019.These frame times do not measure this change. The trace buffer of queue worker 0 fills after about 3.7 s (
trace_dropped), and in the open world frame time follows where the save respawns. This PR shortens shader compiles: the SPIR-V word counts and the cold compile times under Tested are the measurement.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code
https://claude.ai/code/session_01XBXM4pgkMHYEtqN1EQni2P