https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114747

            Bug ID: 114747
           Summary: [RISC-V RVV] Wrong SEW set for mixed-size intrinsics
           Product: gcc
           Version: 13.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: wojciech_mula at poczta dot onet.pl
  Target Milestone: ---

This is a distilled procedure from simdutf project:

---
#include <cstdint>
#include <cstdlib>
#include <riscv_vector.h>

size_t convert_latin1_to_utf16le(const char *src, size_t len, char16_t *dst) {
  char16_t *beg = dst;
  for (size_t vl; len > 0; len -= vl, src += vl, dst += vl) {
    vl = __riscv_vsetvl_e8m4(len);
    vuint8m4_t v = __riscv_vle8_v_u8m4((uint8_t*)src, vl);
    __riscv_vse16_v_u16m8((uint16_t*)dst, __riscv_vzext_vf2_u16m8(v, vl), vl);
  }
  return dst - beg;
}
---

When compiled with gcc 13.2.0 with flags "-march=rv64gcv -O2" it sets a wrong
SEW:

---
convert_latin1_to_utf16le(char const*, unsigned long, char16_t*):
        beq     a1,zero,.L4
        mv      a4,a2
.L3:
        vsetvli a5,a1,e8,m4,ta,ma  # set SEW=8
        vle8.v  v8,0(a0)
        slli    a3,a5,1
        vzext.vf2       v24,v8     # illegal instruction, as SEW/2 < 8
        sub     a1,a1,a5
        vse16.v v24,0(a4)
        add     a0,a0,a5
        add     a4,a4,a3
        bne     a1,zero,.L3
        sub     a0,a4,a2
        srai    a0,a0,1
        ret
.L4:
        li      a0,0
        ret
---

The trunk available on godbold.org (riscv64-unknown-linux-gnu-g++ 14.0.1
20240415) emits vsetvli with e16 argument, which seems to be fine.

Reply via email to