https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127442
Bug ID: 127442
Summary: [14 Regression] RISC‑V: auto-vectorization emits
illegal vsetivli e32,mf2 for Zve32f target
Product: gcc
Version: 14.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: bigmagicreadsun at gmail dot com
Target Milestone: ---
When compiling for -march=rv32gc_zve32f_zvl512b with -O3, GCC 14
auto-vectorizes a simple loop that zeroes an array of 16 uint32_t, but chooses
an illegal vector length multiplier (LMUL) for the given SEW and ELEN. The
generated vsetivli instruction uses SEW=32 and LMUL=1/2, which violates the
RISC‑V V specification constraint:
SEW / LMUL ≤ ELEN
For Zve32f, ELEN = 32. With SEW = 32 and LMUL = 1/2, SEW / LMUL = 64 > 32,
making the vtype value illegal. The hardware (or a strict simulator like QEMU)
will set vtype.vill and subsequent vector instructions will raise an illegal
instruction exception.
This is a regression introduced in GCC 14. The current GCC 15 development
branch (trunk) generates correct code (e.g. vsetivli zero,4,e32,m1,ta,ma or
scalar stores). Users on GCC 14 are therefore exposed to runtime failures on
RISC‑V targets with Zve32f.
Testcase (minimal, triggers the bug):
unsigned int a[16];
void clear_a(void) {
for (int i = 0; i < 16; i++)
a[i] = 0;
}
Actual output (assembly snippet, GCC 14):
clear_a:
vsetivli zero,4,e32,mf2,ta,ma
vmv.v.i v1,0
vse32.v v1,0(a0)
ret
https://godbolt.org/z/b56hbnKMo