]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Fix vfirst/vmsbf/vmsif/vmsof ratio attributes
authorJuzhe-Zhong <juzhe.zhong@rivai.ai>
Mon, 22 Jan 2024 02:49:05 +0000 (10:49 +0800)
committerPan Li <pan2.li@intel.com>
Mon, 22 Jan 2024 07:01:15 +0000 (15:01 +0800)
vfirst/vmsbf/vmsif/vmsof instructions are supposed to demand ratio instead of demanding sew_lmul.
But my previous typo makes VSETVL PASS miss honor the risc-v v spec.

Consider this following simple case:

int foo4 (void * in, void * out)
{
  vint32m1_t v = __riscv_vle32_v_i32m1 (in, 4);
  v = __riscv_vadd_vv_i32m1 (v, v, 4);
  vbool32_t mask = __riscv_vreinterpret_v_i32m1_b32(v);
  mask = __riscv_vmsof_m_b32(mask, 4);
  return __riscv_vfirst_m_b32(mask, 4);
}

Before this patch:

foo4:
        vsetivli        zero,4,e32,m1,ta,ma
        vle32.v v1,0(a0)
        vadd.vv v1,v1,v1
        vsetvli zero,zero,e8,mf4,ta,ma    ----> redundant.
        vmsof.m v2,v1
        vfirst.m        a0,v2
        ret

After this patch:

foo4:
vsetivli zero,4,e32,m1,ta,ma
vle32.v v1,0(a0)
vadd.vv v1,v1,v1
vmsof.m v2,v1
vfirst.m a0,v2
ret

Confirm RVV spec and Clang, this patch makes VSETVL PASS match the correct behavior.

Tested on both RV32/RV64, no regression.

gcc/ChangeLog:

* config/riscv/vector.md: Fix vfirst/vmsbf/vmsof ratio attributes.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/vsetvl/attribute-1.c: New test.

gcc/config/riscv/vector.md
gcc/testsuite/gcc.target/riscv/rvv/vsetvl/attribute-1.c [new file with mode: 0644]

index cfc54ae5eacabc055d7a0f8f8ffa644934f192d0..307d9a8c952e64016795c8d747b8744799a6a4fb 100644 (file)
                          vialu,vshift,vicmp,vimul,vidiv,vsalu,\
                          vext,viwalu,viwmul,vicalu,vnshift,\
                          vimuladd,vimerge,vaalu,vsmul,vsshift,\
-                         vnclip,viminmax,viwmuladd,vmffs,vmsfs,\
+                         vnclip,viminmax,viwmuladd,\
                          vmiota,vmidx,vfalu,vfmul,vfminmax,vfdiv,\
                          vfwalu,vfwmul,vfsqrt,vfrecp,vfsgnj,vfcmp,\
                          vfmerge,vfcvtitof,vfcvtftoi,vfwcvtitof,\
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/attribute-1.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/attribute-1.c
new file mode 100644 (file)
index 0000000..28dcf98
--- /dev/null
@@ -0,0 +1,47 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+int
+foo (void *in, void *out)
+{
+  vint32m1_t v = __riscv_vle32_v_i32m1 (in, 4);
+  v = __riscv_vadd_vv_i32m1 (v, v, 4);
+  vbool32_t mask = __riscv_vreinterpret_v_i32m1_b32 (v);
+  return __riscv_vfirst_m_b32 (mask, 4);
+}
+
+int
+foo2 (void *in, void *out)
+{
+  vint32m1_t v = __riscv_vle32_v_i32m1 (in, 4);
+  v = __riscv_vadd_vv_i32m1 (v, v, 4);
+  vbool32_t mask = __riscv_vreinterpret_v_i32m1_b32 (v);
+  mask = __riscv_vmsbf_m_b32 (mask, 4);
+  return __riscv_vfirst_m_b32 (mask, 4);
+}
+
+int
+foo3 (void *in, void *out)
+{
+  vint32m1_t v = __riscv_vle32_v_i32m1 (in, 4);
+  v = __riscv_vadd_vv_i32m1 (v, v, 4);
+  vbool32_t mask = __riscv_vreinterpret_v_i32m1_b32 (v);
+  mask = __riscv_vmsif_m_b32 (mask, 4);
+  return __riscv_vfirst_m_b32 (mask, 4);
+}
+
+int
+foo4 (void *in, void *out)
+{
+  vint32m1_t v = __riscv_vle32_v_i32m1 (in, 4);
+  v = __riscv_vadd_vv_i32m1 (v, v, 4);
+  vbool32_t mask = __riscv_vreinterpret_v_i32m1_b32 (v);
+  mask = __riscv_vmsof_m_b32 (mask, 4);
+  return __riscv_vfirst_m_b32 (mask, 4);
+}
+
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*4,\s*e32,\s*m1,\s*t[au],\s*m[au]} 4 } } */
+/* { dg-final { scan-assembler-times {vsetivli} 4 } } */
+/* { dg-final { scan-assembler-not {vsetvli} } } */