]> git.ipfire.org Git - thirdparty/gcc.git/commit - gcc/config/riscv/riscv-protos.h
RISC-V: Support FP rint auto-vectorization
authorPan Li <pan2.li@intel.com>
Tue, 26 Sep 2023 02:44:05 +0000 (10:44 +0800)
committerPan Li <pan2.li@intel.com>
Tue, 26 Sep 2023 07:24:50 +0000 (15:24 +0800)
commite4cf5f54cac52f937b7929ba2fac71c059a77f7a
treeee31a2e93bb706c9619928878693c9fa8e6148df
parente2023d2d5ff2e703a025ab5a8d12e27d96efd002
RISC-V: Support FP rint auto-vectorization

This patch would like to support auto-vectorization for the
rint API in math.h. It depends on the -ffast-math option.

When we would like to call rint/rintf like v2 = rint (v1),
we will convert it into below insns (reference the implementation of llvm).

* vfcvt.x.f v3, v1
* vfcvt.f.x v2, v3

However, the floating point value may not need the cvt as above if
its mantissa is zero. Take single precision floating point as example:

Assume we have RTZ rounding mode

  +------------+---------------+-----------------+
  | raw float  | binary layout | after int       |
  +------------+---------------+-----------------+
  | -8388607.5 | 0xcaffffff    | -8388607.0      |
  | 8388607.5  | 0x4affffff    | 8388607.0       |
  | 8388608.0  | 0x4b000000    | 8388608.0       |
  | 8388609.0  | 0x4b000001    | 8388609.0       |
  +------------+---------------+-----------------+

All single floating point >= 8388608.0 will have all zero mantisaa.
We leverage vmflt and mask to filter them out in vector and only do
the cvt on mask.

Befor this patch:
math-rint-1.c:21:1: missed: couldn't vectorize loop
  ...
.L3:
  flw     fa0,0(s0)
  addi    s0,s0,4
  addi    s1,s1,4
  call    rint
  fsw     fa0,-4(s1)
  bne     s0,s2,.L3

After this patch:
  vfabs.v     v2,v1
  vmflt.vf    v0,v2,fa5
  vfcvt.x.f.v v4,v1,v0.t
  vfcvt.f.x.v v2,v4,v0.t
  vfsgnj.vv   v2,v2,v1

Please note VLS mode is also involved in this patch and covered by the
test cases.

gcc/ChangeLog:

* config/riscv/autovec.md (rint<mode>2): New pattern.
* config/riscv/riscv-protos.h (expand_vec_rint): New function decl.
* config/riscv/riscv-v.cc (expand_vec_rint): New function impl.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/unop/math-rint-0.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-rint-1.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-rint-2.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-rint-3.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-rint-run-1.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-rint-run-2.c: New test.
* gcc.target/riscv/rvv/autovec/vls/math-rint-1.c: New test.

Signed-off-by: Pan Li <pan2.li@intel.com>
gcc/config/riscv/autovec.md
gcc/config/riscv/riscv-protos.h
gcc/config/riscv/riscv-v.cc
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-0.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-run-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-rint-run-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/math-rint-1.c [new file with mode: 0644]