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.

Reply via email to