https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128162
Bug ID: 128162
Summary: [17 Regression] wrong code at -O2: vwmacc.vx whose
source is the upper half of the accumulator raises
SIGIL
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: yuki.tanaka at defaultcase dot de
Target Milestone: ---
#include <riscv_vector.h>
__attribute__((noipa)) void a(int *p)
{
vint32m2_t c = __riscv_vle32_v_i32m2(p, 8);
vint16m1_t hi =
__riscv_vget_v_i16m2_i16m1(__riscv_vreinterpret_v_i32m2_i16m2(c), 1);
c = __riscv_vwmacc_vx_i32m2(c, 3, hi, 8);
__riscv_vse32_v_i32m2(p, c, 8);
}
int p[16];
int main(void)
{
a(p);
return 0;
}
$ build-riscv64/gcc/xgcc -B build-riscv64/gcc -O2 -march=rv64gcv -mabi=lp64d -c
vwmacc3.c -o vwmacc3.o
$ riscv64-linux-gnu-gcc -static vwmacc3.s -o vwmacc3
$ qemu-riscv64 -cpu rv64,v=true,vlen=128 ./vwmacc3; echo $?
Illegal instruction qemu-riscv64 -cpu rv64,v=true,vlen=128 ./vwmacc3
132
a adds 3 times the upper half of c to c, and the program must exit with 0, as
it does with GCC 16.1, which copies c with vmv2r.v first. GCC 17 instead emits
vwmacc.vx v2,a5,v3, which reads v3 both as part of the 32-bit accumulator v2-v3
and as the 16-bit source; the RVV spec makes an encoding that reads a register
with two different EEWs reserved. Instead a executes a reserved instruction and
the program is killed with SIGILL.
Compiler Explorer:
https://godbolt.org/z/bWj9YMcfM
Possibly related to r17-3719-gc69c5e7b8e0 ("RISC-V: Allow RVV register overlap
for vwmacc[u].vx").