[all-commits] [llvm/llvm-project] 57ad78: [RISCV][SLP] Use common alignment when checking co...

Kiva via All-commits all-commits at lists.llvm.org
Fri Sep 11 12:10:51 PDT 2026


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 57ad7898dc17e228c3ce1d34a53626080131f384
      https://github.com/llvm/llvm-project/commit/57ad7898dc17e228c3ce1d34a53626080131f384
  Author: Kiva <zengtao at iscas.ac.cn>
  Date:   2026-09-12 (Sat, 12 Sep 2026)

  Changed paths:
    M llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
    M llvm/test/Transforms/SLPVectorizer/RISCV/strided-load-common-alignment.ll

  Log Message:
  -----------
  [RISCV][SLP] Use common alignment when checking constant-stride loads (#222520)

Fix SLP's constant-stride load legality check, which can widen naturally
aligned 32-bit loads into misaligned 64-bit RVV accesses and cause
`SIGBUS`.

In `BoUpSLP::canVectorizeLoads`, the check uses the first sorted load's
alignment, which may be stronger than that of later widened groups. Pass
`CommonAlignment` to `analyzeConstantStrideCandidate` instead, matching
the existing cost model and code generation. This is conservative: it
fixes the legality check without deriving a more precise alignment for
each widened group's starting address, so it may reject some otherwise
legal widening.

### Reproducer

The following reproduces the failure on the tested [SpacemiT K1 / Banana
Pi F3](https://docs.banana-pi.org/en/BPI-F3/BananaPi_BPI-F3) running
RV64 Linux, compiled with `-O3 -march=rv64gcv -mabi=lp64d
-mstrict-align`:

```c
struct Row {
  unsigned x, y, padding[5];
};

_Static_assert(sizeof(unsigned) == 4, "requires 32-bit unsigned");
_Static_assert(sizeof(struct Row) == 28, "requires a 28-byte row");

__attribute__((noinline))
void gather_fields(const struct Row *p, unsigned *restrict out) {
  p = __builtin_assume_aligned(p, 16);
  out[0] = p[0].x + 3;
  out[1] = p[0].y + 3;
  out[2] = p[1].x + 3;
  out[3] = p[1].y + 3;
}

int main(void) {
  _Alignas(16) struct Row rows[2] = {
      {5, 9, {0}}, {11, 17, {0}}};
  unsigned out[4];
  gather_fields(rows, out);
  return out[0] != 8 || out[1] != 12 ||
         out[2] != 14 || out[3] != 20;
}
```

The alignment assumption is satisfied, and the four loads at byte
offsets `0`, `4`, `28`, and `32` are naturally aligned and in bounds.
SLP widens the adjacent pairs into:

```llvm
%v = call <2 x i64> @llvm.experimental.vp.strided.load.v2i64.p0.i64(
    ptr align 4 %p, i64 28, <2 x i1> splat (i1 true), i32 2)
```

On RV64 this lowers to:

```asm
li        a2, 28
vsetivli  zero, 2, e64, m1, ta, ma
vlse64.v  v8, (a0), a2
```

whose second active lane accesses `base + 28`, which is not eight-byte
aligned. The legality check incorrectly uses alignment 16, although the
emitted intrinsic already carries `align 4`.

On the tested machine, the example raises `SIGBUS` before the fix and
returns zero afterward. The fixed compiler uses 32-bit vector loads and
retains vectorized arithmetic.



To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications


More information about the All-commits mailing list