TileOP: eliminate scalar stack round-trips, fix SD-branch dim binding (SuperNPUBench#112) - #92
Merged
Merged
Conversation
Fixes the two codegen patterns from SuperNPUBench#112 and a binding
mixup found while auditing static-value B.DIM forms:
1. Scalar stack round-trips (issue type B): the anti-fold idiom
'volatile T sv = s;' forced every scalar operand (TEXPANDS/TMULS/
TADDS/TCMP/TPREFETCH/TQUANT/...) through a swi/lwi stack round-trip.
Replaced all 78 occurrences with an empty asm register tie:
'T sv = s; asm("" : "+r"(sv));' which keeps the value in a GPR
(anti-fold preserved: B.IOR still binds a real register, never
zero) without touching the stack. Constant scalels now load
directly from the constant pool into the asm input register.
2. keep_acc dead descriptors (issue type A): the zero Quant/LRelu
descriptors are only materialised when the IOR schema reads them
(IorMode != 0); the volatile references moved inside the guarded
branch so parameter-free options emit nothing. (Verified: no
sdi/ldi before B.FPATR on current linx either, #71 already fixed
the emission; this removes the residual hazard.)
3. SD-branch binding mixup (found via the static-value B.DIM audit):
three branches with a static ValidCol and dynamic ValidRow
(TMUL, TROWSUM, TROWEXPANDMUL) bound [valid_col] "r"(GetValidCol())
into lb1 — the wrong dimension, and a compile-time constant into a
register operand. Now binds GetValidRow(). This was the source of
'B.DIM reg, 0' fed by an immediate: after the fix, all 324
register-form B.DIM operands in the per-dimension sweep trace to
genuine runtime defs (loads/parameters), zero immediate-fed.
Verification: issue repro compiles with zero stack round-trips and
zero dead descriptors; full gate 64/74 (11 pre-existing failures
identical on baseline); unittest 40/40; B.IOR zero-constant anti-fold
preserved (B.IOR [a1] with constant-pool load).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the TileOP-side of SuperNPUBench#112 (plus a related binding bug found during verification).
Type A: keep_acc() zero-descriptor dead code
Analysis on current linx: already fixed by #71 — no sdi/ldi is emitted before B.FPATR for parameter-free options (verified by repro). This PR removes the residual hazard: the volatile descriptor references now live inside the
if constexpr (IorMode != 0)guard so parameter-free options cannot resurrect the dead materialisation under any future optimisation level.Type B: scalar constant stack round-trips (swi/lwi)
Confirmed and fixed. Root cause: the anti-fold idiom
volatile T sv = s;(78 occurrences across TEXPANDS/TMULS/TADDS/TCMP/TQUANT/TDEQUANT/TCMP/TPREFETCH/...) forces the scalar through the stack:Replaced with an empty asm register tie
asm("" : "+r"(sv))— the value stays in a GPR (anti-fold preserved: B.IOR binds a real register, verified with the 0.0f worst case) and constants load directly from the pool into the asm input register:Bonus fix: SD-branch dim binding mixup
While auditing whether any static value still reaches
B.DIM reg, 0, found three branches (static ValidCol / dynamic ValidRow: TMUL, TROWSUM, TROWEXPANDMUL) that bound[valid_col] "r"(GetValidCol())into lb1 — the wrong dimension, and a compile-time constant into a register operand. This is exactly what produced "register fed by an immediate then B.DIM reg, 0". Fixed to bind GetValidRow(). After the fix: all 324 register-form B.DIM operands in the per-dimension sweep trace to genuine runtime defs (loads/parameters), zero immediate-fed.Verification
Note: the reported ELF was built with the 0904 toolchain (1ae4ee39); the header-side fixes here apply to any toolchain version. Backend-side constant rematerialisation (c.movr direct move where a stack slot was used) is covered by the same header change — no backend edit needed.