RISC-V: Support FP nearbyint auto-vectorization
This patch would like to support auto-vectorization for the
nearbyint API in math.h. It depends on the -ffast-math option.
When we would like to call nearbyint/nearbyintf like v2 = nearbyint (v1),
we will convert it into below insns (reference the implementation of llvm).
* frflags a5
* vfcvt.x.f v3, v1, RDN
* vfcvt.f.x v2, v3
* fsflags a5
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 nearbyint |
+------------+---------------+-----------------+
|
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-nearbyint-1.c:21:1: missed: couldn't vectorize loop
...
.L3:
flw fa0,0(s0)
addi s0,s0,4
addi s1,s1,4
call nearbyint
fsw fa0,-4(s1)
bne s0,s2,.L3
After this patch:
vfabs.v v2,v1
vmflt.vf v0,v2,fa5
frflags a7
vfcvt.x.f.v v4,v1,v0.t
vfcvt.f.x.v v2,v4,v0.t
fsflags a7
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 (nearbyint<mode>2): New pattern.
* config/riscv/riscv-protos.h (enum insn_type): New enum.
(expand_vec_nearbyint): New function decl.
* config/riscv/riscv-v.cc (expand_vec_nearbyint): New func impl.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/unop/test-math.h: Add helper function.
* gcc.target/riscv/rvv/autovec/unop/math-nearbyint-0.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-nearbyint-1.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-nearbyint-2.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-nearbyint-3.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-nearbyint-run-1.c: New test.
* gcc.target/riscv/rvv/autovec/unop/math-nearbyint-run-2.c: New test.
* gcc.target/riscv/rvv/autovec/vls/math-nearbyint-1.c: New test.
Signed-off-by: Pan Li <pan2.li@intel.com>