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;
}

Reply via email to