Repository navigation
Conversation
…nt offset A loop that stores at an offset from the index, such as a row of a 2-D slice (b[i*ldb+j] = a[i*lda+j], c[row+j] += alpha*x[j]) or a fill that starts part way into a slice (line[off+x] = v), was rejected: loads could be at an offset, but every store had to be at exactly the loop index. A store may now be at the same offsets a load may: i+e, e+i and i-e for a loop-invariant integer e. Every store to one slice must be at the same offset, so each iteration still writes its own element; two offsets are rejected with their own reason. A load of the stored slice at that offset is the same element, ordered after the stores before it as at the index. The dependence test for a load at another offset measures the distance from the store offset instead of from the index, so a constant positive distance in a forward loop is still loaded before any store of the chunk, and a negative or variable distance is rejected as before. An if that selects between stores, and the copy builtin, take the offset too. The emitted store is capped at the limit plus the offset, so the vector loop never writes an element the scalar loop does not, and the length check and the overlap window cover the elements stored. A constant offset that puts every stored index below zero is left alone, as for a load. The vectorized set gains one loop in std (an image/jpeg fill), sixteen in gonum (dlacpy, dlaset, dlascl and dlarfb rows, and testlapack helpers) and five in github.com/thesyncim/goav1; TSVC s423 and s424 now vectorize and match their goldens.
thesyncim
force-pushed
the
offset-store-on-windows
branch
from
November 4, 2026 15:50
9dd4eb0 to
796e0a8
Compare
mauri870
pushed a commit
that referenced
this pull request
Nov 4, 2026
The runners have moved to ubuntu-26.04, so this is the qemu part of #1 you said you'd take when that happened. `qemu-user-static` has no installation candidate there, so every PR now fails at that step and the arm64 runs, the golden check, fmt and lint get skipped. You can see it on #7, #9 and #19, where Build, Test and the amd64 tsvc run all pass first. master's last run predates the move, so the next push will hit it too. `qemu-user` has the static emulators on 26.04, just without the `-static` names, so this installs that and links `qemu-aarch64-static` when it's missing, since the Makefile runs that name. It's been passing on my fork's ubuntu-26.04 runners, and this PR's own CI runs it too.
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.
Loads can already be at
i+e,e+iori-efor a loop-invariante. This allows the same for stores, which covers row-wise code like:Every store to a given slice has to use the same offset, so each iteration still writes its own element. Two different offsets are rejected with a new reason. For loads of a stored slice, the distance is now measured from the store offset instead of from
i. The same offset means the same element. A constant positive distance in a forward loop is loaded before the chunk's stores, as today. A negative distance, a non-constant one, or a loop that counts down is rejected. The store gets its own window, cut at the offset, so the vector loop never writes an element the scalar loop doesn't; the length check and the overlap window include the offset. The if-select and copy-builtin paths take the offset too, and a constant offset that puts the first stored index below zero is rejected, as mauri870#2 does for loads.With
loopvec -json -methods(I read every added loop), std goes from 28 to 29 vectorized loops (animage/jpegfill), gonum from 161 to 177 (dlacpy,dlaset,dlasclanddlarfbrows, plus some testlapack helpers), and goav1 from 81 to 86. TSVC s423 and s424 now vectorize and match their goldens. The generated code for loops that were already vectorized doesn't change.offset_store.txtruns 9 shapes over 14 sizes, plus short slices that must panic and aliased views that must fall back, and both builds have to print the same output.offset_store_no_rewrite.txtpins the rejected cases.