https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128244
Bug ID: 128244
Summary: Bugs in sifive vector extension support
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: law at gcc dot gnu.org
Target Milestone: ---
LLM review of sifive.md has indicate these patterns may have a significant bug.
- @sf_vc_v_vvv_se<mode> and @sf_vc_v_vvv<mode>
- @sf_vc_v_xvv_se<mode> and @sf_vc_v_xvv<mode>
- @sf_vc_v_ivv_se<mode> and @sf_vc_v_ivv<mode>
- @sf_vc_v_fvv_se<mode> and @sf_vc_v_fvv<mode>
- @sf_vc_v_vvw_se<mode> and @sf_vc_v_vvw<mode>
- @sf_vc_v_xvw_se<mode> and @sf_vc_v_xvw<mode>
- @sf_vc_v_ivw_se<mode> and @sf_vc_v_ivw<mode>
- @sf_vc_v_fvw_se<mode> and @sf_vc_v_fvw<mode>
Those patterns write operand 4 in their assembler template, but there is no tie
between operand 4 and operand 0.
Given this testcase compiled with -O2 -march=rv64gcv_xsfvcp
#include
"/home/jefflaw/test/gcc/gcc/testsuite/gcc.target/riscv/rvv/xsfvector/sifive_vector.h"
vuint32m1_t f(vuint32m1_t vd, vuint32m1_t vs2, vuint32m1_t rs1, size_t vl){
vuint32m1_t r = __riscv_sf_vc_v_vvv_u32m1(1, vd, vs2, rs1, vl);
vuint32m1_t q = __riscv_sf_vc_v_vvv_u32m1(2, vd, vs2, rs1, vl);
return __riscv_vadd_vv_u32m1(r, q, vl);
}
The relevant insns from the .final dump:
(insn 9 38 10 (set (reg/v:RVVM1SI 108 v12 [orig:134 r ] [134])
(if_then_else:RVVM1SI (unspec:RVVMF32BI [
(const_vector:RVVMF32BI repeat [
(const_int 1 [0x1])
])
(reg:DI 10 a0 [orig:145 vl ] [145])
(const_int 2 [0x2]) repeated x2
(const_int 0 [0])
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
(unspec_volatile:RVVM1SI [
(const_int 1 [0x1])
(reg:RVVM1SI 104 v8 [orig:142 vd ] [142])
(reg:RVVM1SI 105 v9 [orig:143 vs2 ] [143])
(reg:RVVM1SI 106 v10 [orig:144 rs1 ] [144])
] UNSPECV_SF_CV)
(unspec:RVVM1SI [
(reg:DI 0 zero)
] UNSPEC_VUNDEF))) "w.c":3:19 42039 {sf_vc_v_vvv_servvm1si}
(nil))
(insn 10 9 15 (set (reg/v:RVVM1SI 107 v11 [orig:135 q ] [135])
(if_then_else:RVVM1SI (unspec:RVVMF32BI [
(const_vector:RVVMF32BI repeat [
(const_int 1 [0x1])
])
(reg:DI 10 a0 [orig:145 vl ] [145])
(const_int 2 [0x2]) repeated x2
(const_int 0 [0])
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
(unspec_volatile:RVVM1SI [
(const_int 2 [0x2])
(reg:RVVM1SI 104 v8 [orig:142 vd ] [142])
(reg:RVVM1SI 105 v9 [orig:143 vs2 ] [143])
(reg:RVVM1SI 106 v10 [orig:144 rs1 ] [144])
] UNSPECV_SF_CV)
(unspec:RVVM1SI [
(reg:DI 0 zero)
] UNSPEC_VUNDEF))) "w.c":4:19 42039 {sf_vc_v_vvv_servvm1si}
(expr_list:REG_DEAD (reg:RVVM1SI 106 v10 [orig:144 rs1 ] [144])
(expr_list:REG_DEAD (reg:RVVM1SI 105 v9 [orig:143 vs2 ] [143])
(expr_list:REG_DEAD (reg:RVVM1SI 104 v8 [orig:142 vd ] [142])
(expr_list:REG_DEAD (reg:DI 10 a0 [orig:145 vl ] [145])
(nil))))))
Note how operands4 in both write v8, but there's a write to v12/v11 as
operands[0] in the two insns respecively. We get this output:
sf.vc.v.vvv 1,v8,v10,v9
sf.vc.v.vvv 2,v8,v10,v9
I haven't really dove into this, but it seems like operands[0] and operands[4]
need to be tied together with a matching constraint. But there may be some
reason why that's right that is non-obvious that I've missed.