Skip to content

[comgr][hotswap] Prove scratch liveness from current text - #3618

Merged
lamb-j merged 5 commits into
ROCm:amd-stagingfrom
harsh-amd:users/harsh/hotswap-sgpr-01-current-liveness
Jul 28, 2026
Merged

[comgr][hotswap] Prove scratch liveness from current text#3618
lamb-j merged 5 commits into
ROCm:amd-stagingfrom
harsh-amd:users/harsh/hotswap-sgpr-01-current-liveness

Conversation

@harsh-amd

@harsh-amd harsh-amd commented Jul 26, 2026

Copy link
Copy Markdown

Scope

Add the fail-closed register-liveness primitive needed to reuse scratch
registers safely in later far-return routing changes. The proof:

  • recognizes explicit, implicit, and tied read/modify/write operands;
  • determines whether a replacement consumes an incoming register value before
    overwriting it;
  • synchronously decodes the owning function from the current .text bytes so
    earlier patch writes cannot make a cached decode snapshot stale; and
  • rejects undecodable instructions, invalid boundaries, escaping successors,
    calls, returns, and unresolved control flow.

This first replacement is based directly on current amd-staging; later
replacement PRs will depend on its exact head. It establishes the liveness
prerequisite but does not activate a new corpus rewrite by itself.

Review fixes

The review repair commit eada1e3b9041:

  • makes deferred trampoline mutations visible to current-text liveness;
  • treats s_rfe_i64 as terminating control flow;
  • preserves and rejects MC SoftFail in safety proofs;
  • fails closed on liveness proof gaps and bounds errors;
  • invalidates liveness after specialized in-place VOP3PX2 writes; and
  • adds focused unit coverage for the repaired paths.

The branch was then merged with the current target in 065af42b4b0a.

Validation

Exact head: 065af42b4b0ae8764b19be22d8d4b6176aeb2b99

Exact corpus baseline: 39f443516c145f27e2255a41a232d565c9acb409

All qualification checkouts and builds were created on mi300x.

  • Release HotswapMCTests: 143/143 passed
  • Release HotSwap LIT: 125/125 passed
  • Release supported COMGR LIT: 148/148 passed, 14 unsupported
  • Release COMGR CTest: 31/31 passed
  • ASAN HotswapMCTests: 143/143 passed
  • ASAN supported COMGR LIT: 148/148 passed, 14 unsupported
  • ASAN COMGR CTest: 31/31 passed
  • ASAN/LSAN reports: 0
  • clang-format, git diff --check, focused review, and two independent
    sibling reviews: clean

Corpus qualification status

Both exact baseline and candidate runs evaluated the same 2,685 paths with the
audited four-gate harness, four workers, 1,800-second rewrite timeouts, and no
exclusions:

Variant Success Failure Timeout
baseline 2,558 127 0
candidate 2,558 127 0
  • Corpus safety gate: PASS — zero new failures and zero worsened retained
    failures.
  • Corpus improvement gate: FAIL — zero baseline-failure-to-success
    improvements and no strict reduction in the failing set.

The failed improvement gate remains a blocker to an independent QUALIFIED
verdict, but under the revised qualification procedure it does not stop
MI400-3 functional testing.

MI400-3 qualification status

The complete original-library baseline and isolated candidate matrix is complete
on the current Confluence image. Because the original-library sparse suites
aborted, the authoritative candidate matrix was rerun in a second fresh
container as required by the qualification procedure.

Candidate library SHA-256: 960b67ac1ceb80b74d325730d548171efec6c2c75196d16ae664b24c05792663

Required test set Original library Candidate
HIP named cases 24/24 pass 24/24 pass
hipTensor quick 57/57 pass 57/57 pass
rocPRIM quick 178/178 pass 177/178 pass
rocThrust quick 336/336 pass 336/336 pass
hipSPARSE quick 0/4 pass 0/4 pass
rocSPARSE quick 0/4 pass 0/4 pass
rocSOLVER quick 2/2 pass 2/2 pass
hipBLASLt quick 1/1 pass 1/1 pass
rocThrust test 64 1/1 pass 1/1 pass

The selected quick counts reflect the current procedure: hipTensor uses the
exact ^quick$ label; rocPRIM, rocThrust, and the remaining suites use the
current quick selection, including ffm-quick where applicable.

Blocking MI400-3 findings:

  • Candidate rocPRIM test [MLIR][OpenMP] Fix handling of constant num_teams/threads #204, test_device_partition_gpus_quick_suite,
    timed out at 300.11 seconds in the isolated full matrix. A focused fresh
    A/B subsequently passed with both the original library (92 seconds) and the
    exact candidate (94 seconds), so the timeout was not reproducibly
    candidate-specific; the recorded required-matrix timeout still blocks.
  • All four hipSPARSE and all four rocSPARSE candidate tests aborted with
    HSA_STATUS_ERROR_MEMORY_APERTURE_VIOLATION, matching the original-library
    failing cases and failure class. hipSPARSE test Drano integrated w/ AMD llvm, basic functionality working. #9 took about 228 seconds
    with the candidate versus 3.5 seconds in the original baseline.
  • The GPU continued to enumerate as gfx1250 after the complete matrix; no GPU
    reset or device loss occurred.

MI400-3 therefore FAILS its required pass gate. Together with the failed
corpus improvement gate, PR #3618 is NOT QUALIFIED independently. The
corpus safety gate remains PASS: no new or worsened corpus failures.

@harsh-amd
harsh-amd force-pushed the users/harsh/hotswap-sgpr-01-current-liveness branch from 7d3e665 to 34bdd98 Compare July 26, 2026 04:09
@harsh-amd
harsh-amd force-pushed the users/harsh/hotswap-sgpr-01-current-liveness branch from 8318fad to 6d98b78 Compare July 26, 2026 07:33
@harsh-amd

Copy link
Copy Markdown
Author

CI triage for head 6d98b78d944ebb044340ba85ccf5060438e83712: the Linux and Windows compiler builds, Linux and Windows COMGR tests, SPIR-V tests, compiler-runtime stages, and runtime tests passed. The lone completed failure is Linux::release / Test rocm-examples; all 23 HIP-Basic examples built and passed, then the Applications build failed while compiling monte_carlo_pi because the CI staging environment could not find hipcub/iterator/counting_input_iterator.hpp. This is a missing staged dependency/header, outside this PR’s amd/comgr hotswap-only diff. The PR remains draft pending the combined corpus and MI400 gates.

@lamb-j
lamb-j marked this pull request as ready for review July 27, 2026 17:44
@lamb-j
lamb-j requested review from chinmaydd and lamb-j as code owners July 27, 2026 17:44
@lamb-j

lamb-j commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Moved out of draft to test automate-prs-label

@github-actions github-actions Bot added comgr Related to Code Object Manager hotswap Related to the Comgr Hotswap feature labels Jul 27, 2026
Comment thread amd/comgr/src/hotswap/rewriter/b0a0.cpp Outdated
harsh-amd and others added 5 commits July 28, 2026 07:15
Compute numbered-SGPR and VCC liveness for an entire function with one bounded backward dataflow analysis. Fail closed at unresolved control-flow and register-effect boundaries, account for tied, implicit, pair, and subregister operands, and analyze replacement inputs before selecting scratch registers.

Decode the current text generation instead of the original instruction snapshot. Centralize immediate text writes so every mutation clears cached function data, while preserving failure-atomic NOP-sled emission and bounded memory across repeated patches.

Cover diamonds, loops, calls, returns, traps, real MC barriers, malformed boundaries, mutation-driven rebuilds, replacement boundaries, SGPR limits, register overlap, and a 16K-instruction scaling case.
@harsh-amd
harsh-amd force-pushed the users/harsh/hotswap-sgpr-01-current-liveness branch from 4c2c2b1 to a9e6282 Compare July 28, 2026 14:32
@lamb-j

lamb-j commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Claude code review — #3618

Posted by @lamb-j (Claude Code), using local Comgr context + AGENT_CONVENTIONS.md / HOTSWAP_CONVENTIONS.md. Verified against head a9e6282d.

Recommendation: approve — no blockers. This is a clean, high-quality fail-closed MC-level SGPR/VCC liveness primitive.

  • @jmmartinez's point is resolved: addTrackedSgprBits now returns bool, return falses immediately on an out-of-range SGPR, and every caller bails on failure — fail-closed behavior preserved, no processing after invalid input.
  • Liveness correctness is sound (independently verified): explicit + implicit (implicit_defs/implicit_uses, SCC/VCC/EXEC) + tied RMW operands are all covered via MCInstrDesc + getOperandConstraint(TIED_TO) and MCRegisterInfo::regsOverlap/numberedSgprIndex (no positional or hand-rolled register-range math); read-before-write ordering is correct (use ∪ (out − def), tied source counts as a read); a partial sub-register def (vcc_lo) doesn't kill the aggregate; and the headline synchronous re-decode is realbuildCurrentFunctionSgprLiveness decodes Ctx.Text + FunctionRange.Begin (not the cached Ctx.Decoded), gated by a TextMutationGeneration counter that all writers (writeCurrentText, in-place, VOP3PX2) bump, with a test that mutates through the production VTable writers and proves the verdict reads the new bytes. Every reject path (undecodable, SoftFail, invalid boundary/overflow, escaping successor, call/return/indirect/trap/barrier) defaults conservatively to live, terminating on s_endpgm + mayAffectControlFlow. MC-level liveness genuinely doesn't exist in LLVM (the CodeGen LivePhysRegs/computeRegisterLiveness helpers require MachineInstr/MachineFunction), so this isn't duplicated llvm/ content.

MINOR

  • getInstructionRegisterEffects (b0a0.cpp:112-139) — a tied def is pushed to both Defs and Uses, and the same reg can reappear in the fixed-operand use loop. Harmless for the current bit-vector consumer (duplicates collapse; def+use on one reg is correct RMW), but a latent trap if a future consumer counts operand multiplicity — worth a one-line comment that the sets are membership-only.
  • TargetHasNoVariadicDefOpcodes honestly pins that gfx1250 has zero variadicOpsAreDefs() opcodes, so the variadicOpsAreDefs ? Defs : Uses branch is dead on the target and no runtime test would catch a Defs/Uses swap there. Consider a synthetic-MCInst unit test for that branch, or defer it until a consumer exists.

NIT

  • replacementNeedsIncomingRegister passes Gfx1250MaxSgprs while the current-function path uses Ctx.Config.MaxSgprs — deliberate, but flag for the follow-up consumer PR if per-config tightening is ever wanted.
  • The 14-field PatchContext aggregate-init block is copy-pasted across ~6 tests — a small helper would cut ~120 lines and de-risk field-order mistakes as PatchContext grows.

Test coverage is comprehensive: every reject reason and every live/dead verdict class has a case, including the sync-re-decode-after-production-mutation scenario and the SoftFail-cache-hit subtlety.

@lamb-j
lamb-j merged commit ddc0423 into ROCm:amd-staging Jul 28, 2026
28 of 31 checks passed
lamb-j added a commit to ROCm/TheRock that referenced this pull request Jul 28, 2026
…ing) (#6940)

## Summary

Bumps `compiler/amd-llvm` from `2a67d831` to `8f497e09`, bringing the
**remaining** comgr **hotswap** content from `amd-staging` onto the pin.

Cherry-picked on top of the current pin, in `amd-staging` landed order:

| PR | Title |
|----|-------|
| ROCm/llvm-project#3554 | `[comgr][hotswap] Share conservative liveness
state` |
| ROCm/llvm-project#3555 | `[comgr][hotswap] Size set-PC gateways
without assembly` |
| ROCm/llvm-project#3562 | `[comgr][hotswap] Scale bounded return
analysis` |
| ROCm/llvm-project#3556 | `[comgr][hotswap] Cache kernel metadata in
one pass` |
| ROCm/llvm-project#3274 | `[Comgr][HotSwap] Refactor hotswap related
files into their own directory` |
| ROCm/llvm-project#3576 | `comgr: share far branch gateways across
hotswap sites` |
| ROCm/llvm-project#3618 | `[comgr][hotswap] Prove scratch liveness from
current text` |
| ROCm/llvm-project#3577 | `comgr: handle banked VGPRs in DS and scale16
WMMA rewrites` |
| ROCm/llvm-project#3653 | `[Comgr] Add predicate-driven hotswap
reducer` |
| ROCm/llvm-project#3610 | `[comgr][hotswap] Prove finite indirect
control flow` |
| ROCm/llvm-project#3673 | `[Comgr] Use StringRef::str() in
HotswapMCTest SCOPED_TRACE calls` (gtest portability) |

Each carries a `(cherry picked from ...)` provenance line; all applied
cleanly with no conflicts (including the #3274 directory refactor and
the post-refactor commits).

After the picks, the comgr hotswap sources and tests are
**byte-identical to `amd-staging`** except the previously-dropped
gfx12-5-generic entry-trampoline RUN lines (see #6793) — that trim
carried through the #3274 refactor. None of the new commits add
gfx1251/gfx12-5-generic coverage.

### Numbering
Follows SMP 23.13 (the current pin `2a67d831`), so this is **SMP
23.14**.

ISSUE ID: #6235
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comgr Related to Code Object Manager hotswap Related to the Comgr Hotswap feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants