aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/riscv/autovec.md
diff options
context:
space:
mode:
authorPan Li <pan2.li@intel.com>2023-09-26 10:44:05 +0800
committerPan Li <pan2.li@intel.com>2023-09-26 15:24:50 +0800
commite4cf5f54cac52f937b7929ba2fac71c059a77f7a (patch)
treeee31a2e93bb706c9619928878693c9fa8e6148df /gcc/config/riscv/autovec.md
parente2023d2d5ff2e703a025ab5a8d12e27d96efd002 (diff)
downloadgcc-e4cf5f54cac52f937b7929ba2fac71c059a77f7a.zip
gcc-e4cf5f54cac52f937b7929ba2fac71c059a77f7a.tar.gz
gcc-e4cf5f54cac52f937b7929ba2fac71c059a77f7a.tar.bz2
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>
Diffstat (limited to 'gcc/config/riscv/autovec.md')
-rw-r--r--gcc/config/riscv/autovec.md10
1 files changed, 10 insertions, 0 deletions
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index b47f086..1d2fca6 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -2241,3 +2241,13 @@
DONE;
}
)
+
+(define_expand "rint<mode>2"
+ [(match_operand:V_VLSF 0 "register_operand")
+ (match_operand:V_VLSF 1 "register_operand")]
+ "TARGET_VECTOR && !flag_trapping_math && !flag_rounding_math"
+ {
+ riscv_vector::expand_vec_rint (operands[0], operands[1], <MODE>mode, <VCONVERT>mode);
+ DONE;
+ }
+)