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").

Reply via email to