Skip to content

GVSoC: Strided vector loads execute with unit stride #42

Description

@jpf-h

Hey @Aquaticfuller @DiyouS,

found when running some custom kernels. AI:

AraVlsu::isa_init() binds its handlers by instruction tag:

get_insns_from_tag("vload")          -> handle_insn_load            // unit-stride
get_insns_from_tag("vstore")         -> handle_insn_store           // unit-stride
get_insns_from_tag("vload_strided")  -> handle_insn_load_strided
get_insns_from_tag("vstore_strided") -> handle_insn_store_strided
get_insns_from_tag("vload_indexed")  -> handle_insn_load_indexed
get_insns_from_tag("vstore_indexed") -> handle_insn_store_indexed

In the ISA description every vector memory instruction carried tags=['vload']
or tags=['vstore'] — the strided vlse*.v/vsse*.v and the indexed
vluxei*/vloxei*/vsuxei*/vsoxei* included. No instruction carried the
strided or indexed tags
, so those four handlers were dead code and every
strided/indexed access was executed by the unit-stride handler: the stride
register (or index vector) is ignored and addresses advance by element size.

Ara::isa_init() maps instructions to processing blocks by the same mechanism
(vload/vstore → VLSU, vothers → VFPU, vslide → vslide unit); vector
arithmetic carried no vothers tag either, so it was not dispatched to a
compute block.

Effect

vsse32.v v8, (dst), stride=16 writes 16 consecutive words instead of every
fourth word — it silently overwrites the records it was supposed to skip. In our
case this corrupted a linked list of DMA descriptors and the resulting pointer
loop hung the workload; in general any RVV code using vlse/vsse or indexed
accesses reads and writes the wrong addresses with no diagnostic.

Reproduction

uint32_t src[8], dst[32];            // dst pre-filled with a sentinel
asm volatile("vsetvli t0, %[n], e32, m1, ta, ma\n"
             "vle32.v  v8, (%[s])\n"
             "vsse32.v v8, (%[d]), %[stride]\n"
             :: [n]"r"(8), [s]"r"(src), [d]"r"(dst), [stride]"r"(16) : "memory");

Before the patch dst[1..3], dst[5..7], … are clobbered (the unit-stride
signature). After it, the eight words land at dst[0], dst[4], dst[8], … and
the words between them keep the sentinel.

Fix

Tag the instructions the handlers already expect: 4 strided loads, 4 strided
stores, 8 indexed loads, 8 indexed stores, and the arithmetic instructions as
vothers.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions