This is almost exclusively Jivan's work. His original post:
commitf652a35877e32d470d649d1aee5d94fa0169a478
authorJivan Hakobyan <jivanhakobyan9@gmail.com>
Tue, 30 Apr 2024 15:44:02 +0000 (30 09:44 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Tue, 30 Apr 2024 15:46:10 +0000 (30 09:46 -0600)
tree3a80a59bf6740514b2c392cd89f72b3bc4ee3e1d
parent0b2735e0797fee9b4ec5cd74f22afe0483f888dd
This is almost exclusively Jivan's work.  His original post:

> https://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg336483.html

This patch is primarily meant to improve the code we generate for FP rounding
such as ceil/floor.  It also addresses some unnecessary sign extensions in the
same areas.

RISC-V's FP conversions have a bit of undesirable behavior that make them
non-suitable as-is for ceil/floor and other related functions. These
deficiencies are addressed in the Zfa extension, but there's no reason not to
pick up a nice improvement when we can.

Basically we can still use the basic FP conversions for floor/ceil and friends
when we don't care about inexact exceptions by checking for the special cases
first, then emitting the conversion when the special cases don't apply.  That's
still much faster than calling into glibc.

The redundant sign extensions are eliminated using the same trick Jivan added
last year, just in a few more places ;-)

This eliminates roughly 10% of the dynamic instruction count for imagick.  But
more importantly it's about a 17% performance improvement for that workload
within spec.

This has been bootstrapped as well as regression tested in a cross environment.
It's also successfully built & run specint/specfp correctly.

Pushing to the trunk and the coordination branch momentarily.

gcc/
* config/riscv/iterators.md (fix_ops, fix_uns): New iterators.
(RINT, rint_pattern, rint_rm): Remove unused iterators.
* config/riscv/riscv-protos.h (get_fp_rounding_coefficient): Prototype.
* config/riscv/riscv-v.cc (get_fp_rounding_coefficient): Externalize.
external linkage.
* config/riscv/riscv.md (UNSPEC_LROUND): Remove.
(fix_trunc<ANYF:mode><GPR:mode>2): Replace with ...
(<fix_uns>_trunc<ANYF:mode>si2): New expander & associated insn.
(<fix_uns>_trunc<ANYF:mode>si2_ext): New insn.
(<fix_uns>_trunc<ANYF:mode>di2): Likewise.
(l<rint_pattern><ANYF:mode><GPR:mode>2): Replace with ...
(lrint<ANYF:mode>si2): New expander and associated insn.
(lrint<ANYF:mode>si2_ext, lrint<ANYF:mode>di2): New insns.
(<round_pattern><ANYF:mode>2): Replace with....
(l<round_pattern><ANYF:mode>si2): New expander and associated insn.
(l<round_pattern><ANYF:mode>si2_sext): New insn.
(l<round_pattern><ANYF:mode>di2): Likewise.
(<round_pattern><ANYF:mode>2): New expander.

gcc/testsuite/
* gcc.target/riscv/fix.c: New test.
* gcc.target/riscv/round.c: New test.
* gcc.target/riscv/round_32.c: New test.
* gcc.target/riscv/round_64.c: New test.
gcc/config/riscv/iterators.md
gcc/config/riscv/riscv-protos.h
gcc/config/riscv/riscv-v.cc
gcc/config/riscv/riscv.md
gcc/testsuite/gcc.target/riscv/fix.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/round.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/round_32.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/round_64.c [new file with mode: 0644]