Lowering: LEA.HI with a constant base and no carry (40 vertex programs drawn again) #1437
No reviewers
Labels
No labels
accessibility
autorelease: pending
autorelease: tagged
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
question
testing wanted
wontfix
No milestone
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Hookshot!1437
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/lea-hi-constant"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
LEA.HI Rd, Ra, c[bank][offset], RZ, swith no.Xand no carry out (native op0xa11) stopped the Ampere -> Maxwell lowering with "native constant LEA carry mode". A program that does not lower is never drawn, so 40 of OoT's vertex programs were missing. All three failing encodings in the log havewords[2] = 0x078fd8ff, for example0d007a11 00c03100 078fd8ff 000fe400(programs e9274029dc836a07, 2d279e3ea5e7499f and others).The instruction is the constant plus the high word of
(Ra << s), that isc + (Ra >> (32 - s)). It now lowers the same way as the register form's high word (0x211):operand(1, false));SHR R250 = Ra >> (32 - s), arithmetic when.SX32(bit 73) is set;IADD Rd = R250 + R251.LEA.HI.X.SX32keeps its existing lowering. A carry out, a high source (Rc not RZ) or a zero shift is still refused.Tested
--prepare-shaderson the full shader list (Linux, RTX 4070 Ti, fresh caches): 83 -> 43 programs that do not lower. All 40 "native constant LEA carry mode" programs now lower and compile, and the other failure kinds are unchanged (17 formatted surface load, 3 integer min/max, 3 texel fetch, 3 scratch registers, and so on).hookshot_vk.so.tests/test_lower_lea_hi_constant.py(new, registered inrun_all.pylike the ATOMG test) checks the encodings from the log, an.SX32case and the forms that must still be refused. It fails without this change. The fulltests/run_all.pypasses: 190 passed, 19 skipped for missing tools.🤖 Generated with Claude Code
This landed in the v2.0.12 branch (merged there for testing; it reaches
mainwith that release), so closing. Thanks!Reopened: closing this was a mistake on my side. It was tested in the v2.0.12 branch, and it will be merged into main here, so it shows as merged. Sorry for the noise.
Thanks, this looks right to me.
I decoded the log encoding (
words[2] = 0x078fd8ff): Rc = RZ, bit 80 HI set, bits 81-83 = PT (no carry out), no .X (74), no .SX32 (73), s = 0x1b, and the carry-in field (87-90) is the unused !PT. With Rc = RZ the high word of(Rc:Ra) << sisRa >> (32 - s), logical, and with .SX32 the implied high half is Ra's sign, so it becomes the arithmetic shift. That matches what the 0x211 high-word path and the existing LEA.HI.X.SX32 branch already emit. s is limited to 1..31 by the!= 0check, so32 - sstays in 1..31 for the Maxwell SHR immediate, and the IADD wraps at 32 bits like the native add. No predicate is written: anything with a carry out (or .X, a non-RZ Rc, bit 72, or bits 62-63 negate/abs on the constant) misses the mask and still falls through to the refusal, because bit 80 is set. Ra is read by the SHR before Rd is written, soRd == Rais fine.The test checks the right things (the two log encodings, the .SX32 decode with s = 8 -> SHR 24, .X.SX32 still taking its own branch, and the three refusals), and it's registered in
ARGSintests/run_all.py.Nit: the
case 0xa11header comment still says "LEA with constant base and carry predicate", and this branch has neither. Could say "LEA / LEA.HI with constant base" now.CI was still pending when I looked.