riscvarchive / riscv-gcc

GNU General Public License v2.0
362 stars 275 forks source link

vector intrinsics: 64-bit vmv_v_x only stores lower 32 bits on 32-bit ISA #244

Open Syndace opened 3 years ago

Syndace commented 3 years ago

Example code:

#include <inttypes.h>
#include <stdio.h>
#include <riscv_vector.h>

void main() {
    vsetvl_e64m1(1);

    int64_t a = 1ULL<<63;
    int64_t b;

    vse64_v_i64m1(&b, vmv_v_x_i64m1(a));

    printf("a = %"PRId64"; b = %"PRId64"\n", a, b);
}

Compile using -march=rv32gv.

Explanation:

A value that is greater than 32 bits is stored into a 64-bit vector element using the vmv_v_x instruction. The value is then read from the vector register as '0'. Trying the same experiment with different values reveals that the upper 32 bits of the 64-bit scalar are lost.

The intrinsics documentation states the following:

The compiler may generate multiple instructions for the intrinsics. For example, it is a little bit complicated to support uint64_t operations under XLEN = 32.

It breaks the one-to-one mapping between intrinsics and assembly mnemonics in some hardware configurations. However, it makes more sense for users to use the scalar types consistent with the SEW of vector types.

Given that excerpt, I would expect vmv_v_x to work as expected, even under XLEN=32 and SEW=64.

kito-cheng commented 3 years ago

Oops, it's known issue for us, but thanks for report this.