https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118357
Bug ID: 118357
Summary: risc-v xtheadvector did not handle the logic of vsetvl
properly
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: shuizhuyuanluo at gmail dot com
Target Milestone: ---
original issue https://github.com/XUANTIE-RV/xuantie-gnu-toolchain/issues/24
this issue can be reproduced with upstream gcc too
quote:
the XTheadVector did not handle the logic of vsetvl properly and still simply
reused RVV 1.0. In RVV 1.0, the vsetvli zero,zero,e32,m8 indicates that avl
does not change (avl = 16), but in XTheadVector, it indicates that avl takes
the maximum value (avl = 32). This results in out-of-bounds occurring when the
vector var is stored.
minimal testcase
-------------------------------------------------
riscv64-unknown-linux-gnu-gcc -march=rv64gc_xtheadvector fp16.c -o fp16 -O2
-static
qemu-riscv64 -cpu c906fdv ./fp16
a = -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7
a = -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7
Segmentation fault (core dumped)
-------------------------------------------------
#include <stdio.h>
#include <riscv_vector.h>
int main()
{
float a[16] = {-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7};
fprintf(stderr, "a = ");
for (int i=0; i<16; i++)
{
fprintf(stderr, "%.0f ", a[i]);
}
fprintf(stderr, "\n");
float* ptr = a;
int n = 16;
while (n > 0)
{
size_t vl = __riscv_vsetvl_e32m8(n);
// fp32 -> fp16 -> fp32
vfloat32m8_t _p = __riscv_vle32_v_f32m8(ptr, vl);
vfloat16m4_t _half = __riscv_vfncvt_f_f_w_f16m4(_p, vl);
vfloat32m8_t _out = __riscv_vfwcvt_f_f_v_f32m8(_half, vl);
__riscv_vse32_v_f32m8(ptr, _out, vl);
ptr += vl;
n -= vl;
}
fprintf(stderr, "a = ");
for (int i=0; i<16; i++)
{
fprintf(stderr, "%.0f ", a[i]);
}
fprintf(stderr, "\n");
return 0;
}