diff options
author | Xi Ruoyao <xry111@xry111.site> | 2023-11-18 04:48:20 +0800 |
---|---|---|
committer | Xi Ruoyao <xry111@xry111.site> | 2023-11-29 15:07:08 +0800 |
commit | 530348c418d9ec28aac5b151c15405bfb860e5c4 (patch) | |
tree | 5ec04ab84f642f112e5f21a012438dcd7a29a60a /gcc/fold-const.cc | |
parent | 862867eab78d7731f725cf7fa4ba02ed5e503db1 (diff) | |
download | gcc-530348c418d9ec28aac5b151c15405bfb860e5c4.zip gcc-530348c418d9ec28aac5b151c15405bfb860e5c4.tar.gz gcc-530348c418d9ec28aac5b151c15405bfb860e5c4.tar.bz2 |
LoongArch: Fix usage of LSX and LASX frint/ftint instructions [PR112578]
The usage LSX and LASX frint/ftint instructions had some problems:
1. These instructions raises FE_INEXACT, which is not allowed with
-fno-fp-int-builtin-inexact for most C2x section F.10.6 functions
(the only exceptions are rint, lrint, and llrint).
2. The "frint" instruction without explicit rounding mode is used for
roundM2, this is incorrect because roundM2 is defined "rounding
operand 1 to the *nearest* integer, rounding away from zero in the
event of a tie". We actually don't have such an instruction. Our
frintrne instruction is roundevenM2 (unfortunately, this is not
documented).
3. These define_insn's are written in a way not so easy to hack.
So I removed these instructions and created a "simd.md" file, then added
them and the corresponding expanders there. The advantage of the
simd.md file is we don't need to duplicate the RTL template twice (in
lsx.md and lasx.md).
gcc/ChangeLog:
PR target/112578
* config/loongarch/lsx.md (UNSPEC_LSX_VFTINT_S,
UNSPEC_LSX_VFTINTRNE, UNSPEC_LSX_VFTINTRP,
UNSPEC_LSX_VFTINTRM, UNSPEC_LSX_VFRINTRNE_S,
UNSPEC_LSX_VFRINTRNE_D, UNSPEC_LSX_VFRINTRZ_S,
UNSPEC_LSX_VFRINTRZ_D, UNSPEC_LSX_VFRINTRP_S,
UNSPEC_LSX_VFRINTRP_D, UNSPEC_LSX_VFRINTRM_S,
UNSPEC_LSX_VFRINTRM_D): Remove.
(ILSX, FLSX): Move into ...
(VIMODE): Move into ...
(FRINT_S, FRINT_D): Remove.
(frint_pattern_s, frint_pattern_d, frint_suffix): Remove.
(lsx_vfrint_<flsxfmt>, lsx_vftint_s_<ilsxfmt>_<flsxfmt>,
lsx_vftintrne_w_s, lsx_vftintrne_l_d, lsx_vftintrp_w_s,
lsx_vftintrp_l_d, lsx_vftintrm_w_s, lsx_vftintrm_l_d,
lsx_vfrintrne_s, lsx_vfrintrne_d, lsx_vfrintrz_s,
lsx_vfrintrz_d, lsx_vfrintrp_s, lsx_vfrintrp_d,
lsx_vfrintrm_s, lsx_vfrintrm_d,
<FRINT_S:frint_pattern_s>v4sf2,
<FRINT_D:frint_pattern_d>v2df2, round<mode>2,
fix_trunc<mode>2): Remove.
* config/loongarch/lasx.md: Likewise.
* config/loongarch/simd.md: New file.
(ILSX, ILASX, FLSX, FLASX, VIMODE): ... here.
(IVEC, FVEC): New mode iterators.
(VIMODE): ... here. Extend it to work for all LSX/LASX vector
modes.
(x, wu, simd_isa, WVEC, vimode, simdfmt, simdifmt_for_f,
elebits): New mode attributes.
(UNSPEC_SIMD_FRINTRP, UNSPEC_SIMD_FRINTRZ, UNSPEC_SIMD_FRINT,
UNSPEC_SIMD_FRINTRM, UNSPEC_SIMD_FRINTRNE): New unspecs.
(SIMD_FRINT): New int iterator.
(simd_frint_rounding, simd_frint_pattern): New int attributes.
(<simd_isa>_<x>vfrint<simd_frint_rounding>_<simdfmt>): New
define_insn template for frint instructions.
(<simd_isa>_<x>vftint<simd_frint_rounding>_<simdifmt_for_f>_<simdfmt>):
Likewise, but for ftint instructions.
(<simd_frint_pattern><mode>2): New define_expand with
flag_fp_int_builtin_inexact checked.
(l<simd_frint_pattern><mode><vimode>2): Likewise.
(ftrunc<mode>2): New define_expand. It does not require
flag_fp_int_builtin_inexact.
(fix_trunc<mode><vimode>2): New define_insn_and_split. It does
not require flag_fp_int_builtin_inexact.
(include): Add lsx.md and lasx.md.
* config/loongarch/loongarch.md (include): Include simd.md,
instead of including lsx.md and lasx.md directly.
* config/loongarch/loongarch-builtins.cc
(CODE_FOR_lsx_vftint_w_s, CODE_FOR_lsx_vftint_l_d,
CODE_FOR_lasx_xvftint_w_s, CODE_FOR_lasx_xvftint_l_d):
Remove.
gcc/testsuite/ChangeLog:
PR target/112578
* gcc.target/loongarch/vect-frint.c: New test.
* gcc.target/loongarch/vect-frint-no-inexact.c: New test.
* gcc.target/loongarch/vect-ftint.c: New test.
* gcc.target/loongarch/vect-ftint-no-inexact.c: New test.
Diffstat (limited to 'gcc/fold-const.cc')
0 files changed, 0 insertions, 0 deletions