diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2022-07-12 14:09:44 +0100 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2022-07-12 14:09:44 +0100 |
commit | 00eab0c654e09c8a0f1b1a3b1c7bff8764e64991 (patch) | |
tree | ed24b3892cc22b0ca6d05528e728b019613d2401 /gcc/internal-fn.def | |
parent | 9b06b9d23799ecad5db710e80f214fac0ae175f3 (diff) | |
download | gcc-00eab0c654e09c8a0f1b1a3b1c7bff8764e64991.zip gcc-00eab0c654e09c8a0f1b1a3b1c7bff8764e64991.tar.gz gcc-00eab0c654e09c8a0f1b1a3b1c7bff8764e64991.tar.bz2 |
Add internal functions for iround etc. [PR106253]
The PR is about the aarch64 port using an ACLE built-in function
to vectorise a scalar function call, even though the ECF_* flags for
the ACLE function didn't match the ECF_* flags for the scalar call.
To some extent that kind of difference is inevitable, since the
ACLE intrinsics are supposed to follow the behaviour of the
underlying instruction as closely as possible. Also, using
target-specific builtins has the drawback of limiting further
gimple optimisation, since the gimple optimisers won't know what
the function does.
We handle several other maths functions, including round, floor
and ceil, by defining directly-mapped internal functions that
are linked to the associated built-in functions. This has two
main advantages:
- it means that, internally, we are not restricted to the set of
scalar types that happen to have associated C/C++ functions
- the functions (and thus the underlying optabs) extend naturally
to vectors
This patch takes the same approach for the remaining functions
handled by aarch64_builtin_vectorized_function.
gcc/
PR target/106253
* predict.h (insn_optimization_type): Declare.
* predict.cc (insn_optimization_type): New function.
* internal-fn.def (IFN_ICEIL, IFN_IFLOOR, IFN_IRINT, IFN_IROUND)
(IFN_LCEIL, IFN_LFLOOR, IFN_LRINT, IFN_LROUND, IFN_LLCEIL)
(IFN_LLFLOOR, IFN_LLRINT, IFN_LLROUND): New internal functions.
* internal-fn.cc (unary_convert_direct): New macro.
(expand_convert_optab_fn): New function.
(expand_unary_convert_optab_fn): New macro.
(direct_unary_convert_optab_supported_p): Likewise.
* optabs.cc (expand_sfix_optab): Pass insn_optimization_type to
convert_optab_handler.
* config/aarch64/aarch64-protos.h
(aarch64_builtin_vectorized_function): Delete.
* config/aarch64/aarch64-builtins.cc
(aarch64_builtin_vectorized_function): Delete.
* config/aarch64/aarch64.cc
(TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION): Delete.
* config/i386/i386.cc (ix86_optab_supported_p): Handle lround_optab.
* config/i386/i386.md (lround<X87MODEF:mode><SWI248x:mode>2): Remove
optimize_insn_for_size_p test.
gcc/testsuite/
PR target/106253
* gcc.target/aarch64/vect_unary_1.c: Add tests for iroundf,
llround, iceilf, llceil, ifloorf, llfloor, irintf and llrint.
* gfortran.dg/vect/pr106253.f: New test.
Diffstat (limited to 'gcc/internal-fn.def')
-rw-r--r-- | gcc/internal-fn.def | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def index d2d550d..7c398ba 100644 --- a/gcc/internal-fn.def +++ b/gcc/internal-fn.def @@ -61,6 +61,9 @@ along with GCC; see the file COPYING3. If not see - binary: a normal binary optab, such as vec_interleave_lo_<mode> - ternary: a normal ternary optab, such as fma<mode>4 + - unary_convert: a single-input conversion optab, such as + lround<srcmode><dstmode>2. + - cond_binary: a conditional binary optab, such as cond_add<mode> - cond_ternary: a conditional ternary optab, such as cond_fma_rev<mode> @@ -267,6 +270,26 @@ DEF_INTERNAL_FLT_FLOATN_FN (SQRT, ECF_CONST, sqrt, unary) DEF_INTERNAL_FLT_FN (TAN, ECF_CONST, tan, unary) DEF_INTERNAL_FLT_FN (TANH, ECF_CONST, tanh, unary) +/* Floating-point to integer conversions. + + ??? Here we preserve the I/L/LL prefix convention from the + corresponding built-in functions, rather than make the internal + functions polymorphic in both the argument and the return types. + Perhaps an alternative would be to pass a zero of the required + return type as a second parameter. */ +DEF_INTERNAL_FLT_FN (ICEIL, ECF_CONST, lceil, unary_convert) +DEF_INTERNAL_FLT_FN (IFLOOR, ECF_CONST, lfloor, unary_convert) +DEF_INTERNAL_FLT_FN (IRINT, ECF_CONST, lrint, unary_convert) +DEF_INTERNAL_FLT_FN (IROUND, ECF_CONST, lround, unary_convert) +DEF_INTERNAL_FLT_FN (LCEIL, ECF_CONST, lceil, unary_convert) +DEF_INTERNAL_FLT_FN (LFLOOR, ECF_CONST, lfloor, unary_convert) +DEF_INTERNAL_FLT_FN (LRINT, ECF_CONST, lrint, unary_convert) +DEF_INTERNAL_FLT_FN (LROUND, ECF_CONST, lround, unary_convert) +DEF_INTERNAL_FLT_FN (LLCEIL, ECF_CONST, lceil, unary_convert) +DEF_INTERNAL_FLT_FN (LLFLOOR, ECF_CONST, lfloor, unary_convert) +DEF_INTERNAL_FLT_FN (LLRINT, ECF_CONST, lrint, unary_convert) +DEF_INTERNAL_FLT_FN (LLROUND, ECF_CONST, lround, unary_convert) + /* FP rounding. */ DEF_INTERNAL_FLT_FLOATN_FN (CEIL, ECF_CONST, ceil, unary) DEF_INTERNAL_FLT_FLOATN_FN (FLOOR, ECF_CONST, floor, unary) |