]> git.ipfire.org Git - thirdparty/gcc.git/commit
RISC-V: Add mode switching target hook to insert rounding mode config for fixed-point...
authorJuzhe-Zhong <juzhe.zhong@rivai.ai>
Wed, 17 May 2023 09:58:18 +0000 (17:58 +0800)
committerPan Li <pan2.li@intel.com>
Wed, 17 May 2023 15:16:37 +0000 (23:16 +0800)
commite682d300261c0f2c8a5cc51151adabfe98e1006c
tree5fbb75c67fd45ca1cffe220beabf5c8b8759e34d
parent24bd7168112f96e363cacaf593b3ac0c38c238f9
RISC-V: Add mode switching target hook to insert rounding mode config for fixed-point instructions

Hi, this patch support the new coming fixed-point intrinsics:
https://github.com/riscv-non-isa/rvv-intrinsic-doc/pull/222

Insert fixed-point rounding mode configuration by mode switching target hook.

Mode switching target hook is implemented applying LCM (Lazy code Motion).

So the performance && correctness can be well trusted.

Here is the example:

void f (void * in, void *out, int32_t x, int n, int m)
{
  for (int i = 0; i < n; i++) {
    vint32m1_t v = __riscv_vle32_v_i32m1 (in + i, 4);
    vint32m1_t v2 = __riscv_vle32_v_i32m1_tu (v, in + 100 + i, 4);
    vint32m1_t v3 = __riscv_vaadd_vx_i32m1 (v2, 0, VXRM_RDN, 4);
    v3 = __riscv_vaadd_vx_i32m1 (v3, 3, VXRM_RDN, 4);
    __riscv_vse32_v_i32m1 (out + 100 + i, v3, 4);
  }

  for (int i = 0; i < n; i++) {
    vint32m1_t v = __riscv_vle32_v_i32m1 (in + i + 1000, 4);
    vint32m1_t v2 = __riscv_vle32_v_i32m1_tu (v, in + 100 + i + 1000, 4);
    vint32m1_t v3 = __riscv_vaadd_vx_i32m1 (v2, 0, VXRM_RDN, 4);
    v3 = __riscv_vaadd_vx_i32m1 (v3, 3, VXRM_RDN, 4);
    __riscv_vse32_v_i32m1 (out + 100 + i + 1000, v3, 4);
  }
}

ASM:

...
csrwi   vxrm,2
vsetivli        zero,4,e32,m1,tu,ma
...
Loop 1
...
Loop 2

mode switching can global recognize both Loop 1 and Loop 2 are using RDN
rounding mode and hoist such single "csrwi vxrm,2" to dominate both Loop 1
and Loop 2.

Besides, I have add correctness check sanity tests in this patch too.

Ok for trunk ?

gcc/ChangeLog:

* config/riscv/riscv-opts.h (enum riscv_entity): New enum.
* config/riscv/riscv.cc (riscv_emit_mode_set): New function.
(riscv_mode_needed): Ditto.
(riscv_mode_after): Ditto.
(riscv_mode_entry): Ditto.
(riscv_mode_exit): Ditto.
(riscv_mode_priority): Ditto.
(TARGET_MODE_EMIT): New target hook.
(TARGET_MODE_NEEDED): Ditto.
(TARGET_MODE_AFTER): Ditto.
(TARGET_MODE_ENTRY): Ditto.
(TARGET_MODE_EXIT): Ditto.
(TARGET_MODE_PRIORITY): Ditto.
* config/riscv/riscv.h (OPTIMIZE_MODE_SWITCHING): Ditto.
(NUM_MODES_FOR_MODE_SWITCHING): Ditto.
* config/riscv/riscv.md: Add csrwvxrm.
* config/riscv/vector.md (rnu,rne,rdn,rod,none): New attribute.
(vxrmsi): New pattern.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/vxrm-10.c: New test.
* gcc.target/riscv/rvv/base/vxrm-6.c: New test.
* gcc.target/riscv/rvv/base/vxrm-7.c: New test.
* gcc.target/riscv/rvv/base/vxrm-8.c: New test.
* gcc.target/riscv/rvv/base/vxrm-9.c: New test.
gcc/config/riscv/riscv-opts.h
gcc/config/riscv/riscv.cc
gcc/config/riscv/riscv.h
gcc/config/riscv/riscv.md
gcc/config/riscv/vector.md
gcc/testsuite/gcc.target/riscv/rvv/base/vxrm-10.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/vxrm-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/vxrm-7.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/vxrm-8.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/vxrm-9.c [new file with mode: 0644]