Repository navigation
fix(mir-importer): lower from-end ConstantIndex after Subslice - #1343
Merged
nihalpasham merged 6 commits intoOct 17, 2026
Merged
Conversation
Signed-off-by: Yunus Mutlu <mutluyunus708@gmail.com>
YunusMutlu
force-pushed
the
fix/subslice-from-end-constant-index
branch
from
October 13, 2026 11:30
7eda354 to
d828864
Compare
Rewrite the two nested `if let` helpers as let chains. CI lints every example with `-D warnings`, and the nested form failed clippy::collapsible_match and clippy::collapsible_if. The let chain keeps the `(*_1)[1:-1][-1 of 1]` projection that clippy's own suggestion would have removed. Add a runtime-length case. The four-element cases fold to one constant store once LLVM inlines the helpers, so their PTX never performs the from-end arithmetic. The new case slices a local eight-element buffer at a length read from the row data (3 to 8), runs both from-end writes and a from-end read, and checks a packed result against the same helpers on the host. Its PTX keeps `[%rd+-8]` and `[%rd+-12]` accesses off `base + (n << 2)` behind the pattern-length guards. The README now says the example also covers the from-end case, counts eight cases, and names the nested Subslice chains that still fail loudly. Signed-off-by: nihalpasham <nihalp@nvidia.com>
The address walker's doc comment names the two chains that still return `Ok(None)` on purpose: a slice Subslice that does not directly follow a fat Deref, and a from-end ConstantIndex on a base without a slice length. The from-end index helper cites rustc's MIR validator rule, `offset` at most `min_length`, as the reason the subtraction cannot wrap. The value walker's Subslice arm records that the rebuilt fat value is also kept for a following from-end ConstantIndex, whose arm reads field 1 for the length, so the data-pointer filter must stay restricted to Index and forward ConstantIndex. The array branch of the ConstantIndex arm asserts in debug builds that no from-end index reaches it. The two single-projection bail-outs no longer say "not yet supported": rustc emits `from_end` only for slice patterns and its validator rejects arrays indexed from the end, so a from-end index on a bare local cannot occur in valid MIR. Signed-off-by: nihalpasham <nihalp@nvidia.com>
The README said a from-end index after a Subslice still fails closed. It now takes the rebuilt subslice length, and the subslice_projection example covers that case. Other bases without fat-deref provenance still fail closed. Signed-off-by: nihalpasham <nihalp@nvidia.com>
Only the mutable case folds to a constant store; the field case keeps a load with a constant element offset. Signed-off-by: nihalpasham <nihalp@nvidia.com>
Collaborator
|
/ok to test 0c8561c |
Collaborator
|
Thanks, this is the right fix and it matches what rustc's own backend does. Three small things on top:
8/8 cases pass on the 5090 with memcheck and synccheck clean, the five older kernels give the same PTX as main, and all |
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.
What this adds
A from-end
ConstantIndexthat follows a sliceSubslicenow lowers in both MIR place walkers. rustc emits this chain for nested slice patterns:[_, middle @ .., _]rebuilds the slice as(data + from, len - from - to), and[.., last]onmiddleindexes it asrebuilt_len - offset. The importer previously knew a slice length only directly after a fat-slice deref and rejected the projection, on the read path and on the write path.What we fixed
Subsliceis followed by a from-endConstantIndex, the rebuilt subslice's length is extracted alongside its data pointer and carried into the existing from-end arm, which computeslen - offsetand offsets the element pointer.ConstantIndexrequires the current value to be the rebuilt fat slice or a reconstructed slice tail, extracts its length, and feeds the runtime index into the existing pointer-offset path; the forward-index path is unchanged.((*_1).1: [u32])[-1 of 1], which main rejected.subslice_projectiongains a from-end-plus-Field read, a mutable case with two from-end offsets and collateral-write detection, and a runtime-length case whose PTX keeps the from-end addressing. Theconstant_index_from_endREADME no longer says the after-Subslice case fails closed.Implementation
place_addr.rs: the Deref-to-Subslice continuation accepts anyConstantIndex; for a from-end follower it setscurrent_slice_lenfrom field 1 of the rebuiltmir.construct_slice, and the consumed-Subslice skip re-arms it for one iteration so the pre-existing from-end arm seesentered_slice_len.emit_from_end_slice_indexbecomespub(super).place_iter.rs: theConstantIndexarm computes aruntime_indexforfrom_endfrom theMirSliceTypecurrent value viaemit_slice_len_extractandemit_from_end_slice_index; thePtrpath uses it instead of the i32 constant. A non-slice base fails loudly withfrom-end ConstantIndex requires preserved slice metadata.min_lengthis ignored as inrustc_codegen_ssa, which binds it_; rustc's MIR validator rejectsoffset > min_lengthand the pattern-length test dominates every use, solen - offsetcannot wrap on an executed path.Subsliceprojections #754 addedSubslice; fix(mir-importer): lower Index on slice-tailed DST values #873 added the slice-tail reconstruction the value walker now also accepts.Subslice -> Subsliceand aSubsliceon a slice-tail field still punt loudly withslice Subslice reached iterative lowering without preserved fat-pointer metadata, as on main; documented in the example README and the walker doc comment.Verification
Checked at
0c8561c59(the PR head merged with maine84e5b3d7):middle_last_fieldand, in isolation, at*last += 11, with the message quoted in mir-importer: from-end ConstantIndex after slice Subslice is unsupported #1342.cargo oxide run subslice_projectionon sm_120a, RTX 5090, CUDA 13.4: 8/8 PASS and theSUCCESSmarker; compute-sanitizer memcheck 0 errors and 0 bytes leaked, synccheck 0 errors.[%rd+-8]for[.., last]and[%rd+-12]for[.., second_last, _], offbase + (len << 2)behind the pattern-length guards; the pre-opt IR carriessub i64 %len, 2thensub i64 %sublen, offsetfeedinggetelementptr inboundsfor every from-end helper.OptionDowncast read and write,&[[u32; N]]row then column,&[&u32]and&[&mut u32]then Deref,[first, .., last]on one rebuilt subslice,from: 0andfrom: 2, runtime lengths 3 to 9 with offsets 1, 2 and 4; memcheck clean.cargo test -p mir-importer: 1169 passed. clippy and rustdoc onmir-importerwith-D warnings, the per-example clippy step (which failed at the PR head with 4 errors),cargo oxide fmt --check, 18 repository guards andsync-example-locks.sh --checkall clean. All 60 CI checks passed.just check,cargo oxide build --arch sm_120 subslice_projection, runtime pass on an RTX 3050 Ti Laptop GPU, sm_86.Caveats
Subslice -> SubsliceandSubsliceon a slice-tail field remain unsupported and fail loudly; tracked separately.just checkdoes not lint the example directories; CI does, with-D warnings.Closes #1342.