Repository navigation
Conversation
thesyncim
force-pushed
the
offset-store
branch
from
October 31, 2026 19:07
4ee6df9 to
f0ba4c1
Compare
ubuntu-latest is now ubuntu-26.04, which has no qemu-user-static package, so every run fails at the install step and skips the arm64 tsvc run, the golden check, fmt and lint. qemu-user ships the static emulators there; link qemu-aarch64-static to it when the name is missing, as the Makefile runs that name.
thesyncim
force-pushed
the
offset-store
branch
2 times, most recently
from
October 31, 2026 19:56
76a918b to
b038e67
Compare
Go tip writes export data in iexport version 4, which encodes float constants exactly. x/tools v0.51.0, and the v0.52.0 release, read only up to version 3, so on tip go/packages fails for every package: cannot import "math" (unstable iexport format version 4, just rebuild compiler and std library), export data is newer version - update tool and every script that runs loopvec fails in the tip job. x/tools master reads version 4 (golang/tools@966056e2637c). Update to it until a release includes it. The pinned toolchain is unaffected.
thesyncim
force-pushed
the
offset-store
branch
from
October 31, 2026 20:50
b038e67 to
9dcfc44
Compare
go1.27.3 is the latest 1.27 release. Its simd package is the same as go1.27.1's, so the capability table only changes in its header, and the -methods crash (golang/go#80657) is still there, as flag_methods_ice.txt checks. go.mod keeps go 1.27.1: that is the first release whose simd package loopvec's output compiles against (go1.27.0's ShiftAllRight takes a uint8).
A read at a negative constant offset in a loop with a constant limit, such as dst[i] = a[i-20] + 1 in a loop that stops before 16, was rewritten into code that does not compile: the length check of the vector loop is _ = a[16-21], a negative constant index. -split wrote that file, and the toolexec wrapper fell back to the original package. Such a loop panics as soon as it runs, as does one whose first index is a negative constant (a[i-1] in a loop from 0). Both are now left alone with their own reason, the way a constant limit of zero or less already is. A read whose indexes can all be zero or more (a[i-1] from 1) is still rewritten. The checks read the start and limit as text, so a named constant or a constant expression (const s0 = 0; for i := s0; ...) slipped past them. A constant start or limit is now spelled as its value, which also lets the short-loop rule see a named constant trip count: goav1's for x := range restorationExtraHorz, three iterations, is no longer rewritten. The vectorized set of std and gonum does not change.
…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
branch
from
October 31, 2026 21:50
9dcfc44 to
34d26f9
Compare
Owner
Author
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 is capped atlimit+offset, and the length check and the overlap window include the offset. The if-select and copy-builtin paths take the offset too.With
loopvec -json -methods(I read every added loop), std goes from 34 to 35 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.offset_store_no_rewrite.txtpins the rejected cases.Heads-up: this conflicts with #3, and git merges the two without a conflict into wrong code, because
destination()here doesn't know about #3's windows. Whichever one lands second needsdestinationto defer to the window when there is one. I have that version ready onthesyncim:offset-store-on-windowsand can push it here once #3 is in.The check for stored indices below zero reuses the one from #1.