RISC-V Vector Loops: Advance by the Returned vl Rather Than an Assumed Register Width

A RISC-V vector loop passes a test on one core but skips elements on another. Its pointer increment uses an assumed maximum lane count even though vsetvli returned a smaller active length. The portable loop must advance by the returned vl, not by a guessed vector-register width.

The interesting case is not only the final short tail. The architecture permits different legal choices when the remaining work lies between one and two maximum-sized vectors.

Derive capacity from the selected vector type

The V 1.0 specification defines VLMAX = LMUL × VLEN / SEW. VLEN is the architectural vector-register size, SEW is the selected element width, and LMUL describes the register grouping.

Changing SEW or LMUL can change the element capacity even on the same processor. A byte count based only on VLEN therefore does not describe how many elements a particular instruction sequence processes.

vsetvli takes an application vector length, or AVL, and establishes the active vl for the requested type. Preserve that returned active length and use it to update both the remaining-element count and the address increments appropriate to each operand's element size.

Do not assume min(AVL, VLMAX) in every case

For supported settings, when AVL is at most VLMAX, the active length equals AVL. When AVL is at least twice VLMAX, it equals VLMAX. Between those boundaries, the specification permits a value from ceil(AVL/2) through VLMAX, selected deterministically for the same inputs on a given implementation.

With hypothetical VLMAX 8 and AVL 13, the first iteration may legally process 7 or 8 elements. A loop that processes 7 but advances its pointer by 8 skips an element. Both a 7+6 partition and an 8+5 partition are consistent with the rules.

For 32-bit elements, a returned vl of 7 means advancing that operand by 28 bytes, not 32. If another operand has a different element width in a mixed-width loop, derive its increment separately from the same number of processed elements.

Diagram comparing legal 7-plus-6 and 8-plus-5 vector partitions for thirteen elements and a maximum active length of eight.
Original strip-mining arithmetic example. The vector capacity is hypothetical and no vector test was executed.

Tail policy does not initialize unused elements

Tail-agnostic behavior allows inactive tail destination elements to retain their old contents or be overwritten with ones. It does not promise zero-filled tail lanes. Software that later consumes those lanes as valid data can therefore depend accidentally on one implementation's behavior.

Keep the active-length accounting explicit through the final store or reduction. Choose tail-undisturbed behavior when the algorithm actually requires preservation, and do not infer preserved values from a previous run using an agnostic policy.

Unsupported type settings are another branch. The specification defines vill handling and normally sets vl to zero for an unsupported vtype, while allowing trapping implementations as described there. A loop must not turn a zero-progress configuration into an infinite iteration over a nonzero remaining count.

Calls can invalidate the loop's vector configuration

The pinned RISC-V psABI calling convention does not preserve vl or vtype across ordinary procedure calls. A helper inserted inside a hand-written loop can therefore invalidate the configuration assumed by its next vector instruction.

Re-establish the required configuration after a call under the applicable calling convention, and preserve any scalar bookkeeping the caller needs. Do not confuse saving the returned scalar length with preserving the hardware's current vector state.

A proposed boundary suite includes zero elements, VLMAX, VLMAX+1, 2×VLMAX−1 and 2×VLMAX, using an implementation's supported type. Compare every output element and guard region, not just a checksum of the first vector. These are proposed tests; no vector binary or simulator was run here.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *