From b6c464fe9e1983f7f9d9f1ceb5e12f70b56c50b1 Mon Sep 17 00:00:00 2001 From: rsandifo Date: Tue, 17 Nov 2015 18:55:13 +0000 Subject: [PATCH] Make builtin_vectorized_function take a combined_fn This patch replaces the fndecl argument to builtin_vectorized_function with a combined_fn and gets the vectoriser to call it for internal functions too. The patch also moves vectorisation of machine-specific built-ins to a new hook, builtin_md_vectorized_function. Tested on x86_64-linux-gnu, aarch64-linux-gnu, arm-linux-gnu and powerpc64-linux-gnu. gcc/ * target.def (builtin_vectorized_function): Take a combined_fn (in the form of an unsigned int) rather than a function decl. (builtin_md_vectorized_function): New. * targhooks.h (default_builtin_vectorized_function): Replace the fndecl argument with an unsigned int. (default_builtin_md_vectorized_function): Declare. * targhooks.c (default_builtin_vectorized_function): Replace the fndecl argument with an unsigned int. (default_builtin_md_vectorized_function): New function. * doc/tm.texi.in (TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION): New hook. * doc/tm.texi: Regenerate. * tree-vect-stmts.c (vectorizable_function): Update call to builtin_vectorized_function, also passing internal functions. Call builtin_md_vectorized_function for target-specific builtins. * config/aarch64/aarch64-protos.h (aarch64_builtin_vectorized_function): Replace fndecl argument with an unsigned int. * config/aarch64/aarch64-builtins.c: Include case-cfn-macros.h. (aarch64_builtin_vectorized_function): Update after above changes. Use CASE_CFN_*. * config/arm/arm-protos.h (arm_builtin_vectorized_function): Replace fndecl argument with an unsigned int. * config/arm/arm-builtins.c: Include case-cfn-macros.h (arm_builtin_vectorized_function): Update after above changes. Use CASE_CFN_*. * config/i386/i386.c: Include case-cfn-macros.h (ix86_veclib_handler): Take a combined_fn rather than a built_in_function. (ix86_veclibabi_svml, ix86_veclibabi_acml): Likewise. Use mathfn_built_in rather than calling builtin_decl_implicit directly. (ix86_builtin_vectorized_function) Update after above changes. Use CASE_CFN_*. * config/rs6000/rs6000.c: Include case-cfn-macros.h (rs6000_builtin_vectorized_libmass): Replace fndecl argument with a combined_fn. Use CASE_CFN_*. Use mathfn_built_in rather than calling builtin_decl_implicit directly. (rs6000_builtin_vectorized_function): Update after above changes. Use CASE_CFN_*. Move BUILT_IN_MD to... (rs6000_builtin_md_vectorized_function): ...this new function. (TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION): Define. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@230491 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 44 +++ gcc/config/aarch64/aarch64-builtins.c | 207 +++++++------- gcc/config/aarch64/aarch64-protos.h | 5 +- gcc/config/arm/arm-builtins.c | 107 ++++--- gcc/config/arm/arm-protos.h | 2 +- gcc/config/i386/i386.c | 276 ++++++------------ gcc/config/rs6000/rs6000.c | 524 ++++++++++++++++------------------ gcc/doc/tm.texi | 12 +- gcc/doc/tm.texi.in | 2 + gcc/target.def | 20 +- gcc/targhooks.c | 12 +- gcc/targhooks.h | 3 +- gcc/tree-vect-stmts.c | 22 +- 13 files changed, 577 insertions(+), 659 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c6ddc5a..5c6a83d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,49 @@ 2015-11-17 Richard Sandiford + * target.def (builtin_vectorized_function): Take a combined_fn (in + the form of an unsigned int) rather than a function decl. + (builtin_md_vectorized_function): New. + * targhooks.h (default_builtin_vectorized_function): Replace the + fndecl argument with an unsigned int. + (default_builtin_md_vectorized_function): Declare. + * targhooks.c (default_builtin_vectorized_function): Replace the + fndecl argument with an unsigned int. + (default_builtin_md_vectorized_function): New function. + * doc/tm.texi.in (TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION): + New hook. + * doc/tm.texi: Regenerate. + * tree-vect-stmts.c (vectorizable_function): Update call to + builtin_vectorized_function, also passing internal functions. + Call builtin_md_vectorized_function for target-specific builtins. + * config/aarch64/aarch64-protos.h + (aarch64_builtin_vectorized_function): Replace fndecl argument + with an unsigned int. + * config/aarch64/aarch64-builtins.c: Include case-cfn-macros.h. + (aarch64_builtin_vectorized_function): Update after above changes. + Use CASE_CFN_*. + * config/arm/arm-protos.h (arm_builtin_vectorized_function): Replace + fndecl argument with an unsigned int. + * config/arm/arm-builtins.c: Include case-cfn-macros.h + (arm_builtin_vectorized_function): Update after above changes. + Use CASE_CFN_*. + * config/i386/i386.c: Include case-cfn-macros.h + (ix86_veclib_handler): Take a combined_fn rather than a + built_in_function. + (ix86_veclibabi_svml, ix86_veclibabi_acml): Likewise. Use + mathfn_built_in rather than calling builtin_decl_implicit directly. + (ix86_builtin_vectorized_function) Update after above changes. + Use CASE_CFN_*. + * config/rs6000/rs6000.c: Include case-cfn-macros.h + (rs6000_builtin_vectorized_libmass): Replace fndecl argument + with a combined_fn. Use CASE_CFN_*. Use mathfn_built_in rather + than calling builtin_decl_implicit directly. + (rs6000_builtin_vectorized_function): Update after above changes. + Use CASE_CFN_*. Move BUILT_IN_MD to... + (rs6000_builtin_md_vectorized_function): ...this new function. + (TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION): Define. + +2015-11-17 Richard Sandiford + * tree-vect-patterns.c: Include internal-fn.h. (vect_recog_pow_pattern): Use IFN_SQRT instead of BUILT_IN_SQRT*. diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c index 6b4208f..c4cda4f 100644 --- a/gcc/config/aarch64/aarch64-builtins.c +++ b/gcc/config/aarch64/aarch64-builtins.c @@ -38,6 +38,7 @@ #include "expr.h" #include "langhooks.h" #include "gimple-iterator.h" +#include "case-cfn-macros.h" #define v8qi_UP V8QImode #define v4hi_UP V4HImode @@ -1258,7 +1259,8 @@ aarch64_expand_builtin (tree exp, } tree -aarch64_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in) +aarch64_builtin_vectorized_function (unsigned int fn, tree type_out, + tree type_in) { machine_mode in_mode, out_mode; int in_n, out_n; @@ -1282,130 +1284,119 @@ aarch64_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in) : (AARCH64_CHECK_BUILTIN_MODE (2, S) \ ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_##N##v2sf] \ : NULL_TREE))) - if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) + switch (fn) { - enum built_in_function fn = DECL_FUNCTION_CODE (fndecl); - switch (fn) - { #undef AARCH64_CHECK_BUILTIN_MODE #define AARCH64_CHECK_BUILTIN_MODE(C, N) \ (out_mode == N##Fmode && out_n == C \ && in_mode == N##Fmode && in_n == C) - case BUILT_IN_FLOOR: - case BUILT_IN_FLOORF: - return AARCH64_FIND_FRINT_VARIANT (floor); - case BUILT_IN_CEIL: - case BUILT_IN_CEILF: - return AARCH64_FIND_FRINT_VARIANT (ceil); - case BUILT_IN_TRUNC: - case BUILT_IN_TRUNCF: - return AARCH64_FIND_FRINT_VARIANT (btrunc); - case BUILT_IN_ROUND: - case BUILT_IN_ROUNDF: - return AARCH64_FIND_FRINT_VARIANT (round); - case BUILT_IN_NEARBYINT: - case BUILT_IN_NEARBYINTF: - return AARCH64_FIND_FRINT_VARIANT (nearbyint); - case BUILT_IN_SQRT: - case BUILT_IN_SQRTF: - return AARCH64_FIND_FRINT_VARIANT (sqrt); + CASE_CFN_FLOOR: + return AARCH64_FIND_FRINT_VARIANT (floor); + CASE_CFN_CEIL: + return AARCH64_FIND_FRINT_VARIANT (ceil); + CASE_CFN_TRUNC: + return AARCH64_FIND_FRINT_VARIANT (btrunc); + CASE_CFN_ROUND: + return AARCH64_FIND_FRINT_VARIANT (round); + CASE_CFN_NEARBYINT: + return AARCH64_FIND_FRINT_VARIANT (nearbyint); + CASE_CFN_SQRT: + return AARCH64_FIND_FRINT_VARIANT (sqrt); #undef AARCH64_CHECK_BUILTIN_MODE #define AARCH64_CHECK_BUILTIN_MODE(C, N) \ (out_mode == SImode && out_n == C \ && in_mode == N##Imode && in_n == C) - case BUILT_IN_CLZ: - { - if (AARCH64_CHECK_BUILTIN_MODE (4, S)) - return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_clzv4si]; - return NULL_TREE; - } - case BUILT_IN_CTZ: - { - if (AARCH64_CHECK_BUILTIN_MODE (2, S)) - return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_ctzv2si]; - else if (AARCH64_CHECK_BUILTIN_MODE (4, S)) - return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_ctzv4si]; - return NULL_TREE; - } + CASE_CFN_CLZ: + { + if (AARCH64_CHECK_BUILTIN_MODE (4, S)) + return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_clzv4si]; + return NULL_TREE; + } + CASE_CFN_CTZ: + { + if (AARCH64_CHECK_BUILTIN_MODE (2, S)) + return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_ctzv2si]; + else if (AARCH64_CHECK_BUILTIN_MODE (4, S)) + return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_ctzv4si]; + return NULL_TREE; + } #undef AARCH64_CHECK_BUILTIN_MODE #define AARCH64_CHECK_BUILTIN_MODE(C, N) \ (out_mode == N##Imode && out_n == C \ && in_mode == N##Fmode && in_n == C) - case BUILT_IN_LFLOOR: - case BUILT_IN_LFLOORF: - case BUILT_IN_LLFLOOR: - case BUILT_IN_IFLOORF: - { - enum aarch64_builtins builtin; - if (AARCH64_CHECK_BUILTIN_MODE (2, D)) - builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv2dfv2di; - else if (AARCH64_CHECK_BUILTIN_MODE (4, S)) - builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv4sfv4si; - else if (AARCH64_CHECK_BUILTIN_MODE (2, S)) - builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv2sfv2si; - else - return NULL_TREE; - - return aarch64_builtin_decls[builtin]; - } - case BUILT_IN_LCEIL: - case BUILT_IN_LCEILF: - case BUILT_IN_LLCEIL: - case BUILT_IN_ICEILF: - { - enum aarch64_builtins builtin; - if (AARCH64_CHECK_BUILTIN_MODE (2, D)) - builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv2dfv2di; - else if (AARCH64_CHECK_BUILTIN_MODE (4, S)) - builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv4sfv4si; - else if (AARCH64_CHECK_BUILTIN_MODE (2, S)) - builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv2sfv2si; - else - return NULL_TREE; - - return aarch64_builtin_decls[builtin]; - } - case BUILT_IN_LROUND: - case BUILT_IN_IROUNDF: - { - enum aarch64_builtins builtin; - if (AARCH64_CHECK_BUILTIN_MODE (2, D)) - builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv2dfv2di; - else if (AARCH64_CHECK_BUILTIN_MODE (4, S)) - builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv4sfv4si; - else if (AARCH64_CHECK_BUILTIN_MODE (2, S)) - builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv2sfv2si; - else - return NULL_TREE; - - return aarch64_builtin_decls[builtin]; - } - case BUILT_IN_BSWAP16: + CASE_CFN_IFLOOR: + CASE_CFN_LFLOOR: + CASE_CFN_LLFLOOR: + { + enum aarch64_builtins builtin; + if (AARCH64_CHECK_BUILTIN_MODE (2, D)) + builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv2dfv2di; + else if (AARCH64_CHECK_BUILTIN_MODE (4, S)) + builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv4sfv4si; + else if (AARCH64_CHECK_BUILTIN_MODE (2, S)) + builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv2sfv2si; + else + return NULL_TREE; + + return aarch64_builtin_decls[builtin]; + } + CASE_CFN_ICEIL: + CASE_CFN_LCEIL: + CASE_CFN_LLCEIL: + { + enum aarch64_builtins builtin; + if (AARCH64_CHECK_BUILTIN_MODE (2, D)) + builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv2dfv2di; + else if (AARCH64_CHECK_BUILTIN_MODE (4, S)) + builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv4sfv4si; + else if (AARCH64_CHECK_BUILTIN_MODE (2, S)) + builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv2sfv2si; + else + return NULL_TREE; + + return aarch64_builtin_decls[builtin]; + } + CASE_CFN_IROUND: + CASE_CFN_LROUND: + CASE_CFN_LLROUND: + { + enum aarch64_builtins builtin; + if (AARCH64_CHECK_BUILTIN_MODE (2, D)) + builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv2dfv2di; + else if (AARCH64_CHECK_BUILTIN_MODE (4, S)) + builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv4sfv4si; + else if (AARCH64_CHECK_BUILTIN_MODE (2, S)) + builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv2sfv2si; + else + return NULL_TREE; + + return aarch64_builtin_decls[builtin]; + } + case CFN_BUILT_IN_BSWAP16: #undef AARCH64_CHECK_BUILTIN_MODE #define AARCH64_CHECK_BUILTIN_MODE(C, N) \ (out_mode == N##Imode && out_n == C \ && in_mode == N##Imode && in_n == C) - if (AARCH64_CHECK_BUILTIN_MODE (4, H)) - return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv4hi]; - else if (AARCH64_CHECK_BUILTIN_MODE (8, H)) - return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv8hi]; - else - return NULL_TREE; - case BUILT_IN_BSWAP32: - if (AARCH64_CHECK_BUILTIN_MODE (2, S)) - return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv2si]; - else if (AARCH64_CHECK_BUILTIN_MODE (4, S)) - return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv4si]; - else - return NULL_TREE; - case BUILT_IN_BSWAP64: - if (AARCH64_CHECK_BUILTIN_MODE (2, D)) - return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv2di]; - else - return NULL_TREE; - default: - return NULL_TREE; - } + if (AARCH64_CHECK_BUILTIN_MODE (4, H)) + return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv4hi]; + else if (AARCH64_CHECK_BUILTIN_MODE (8, H)) + return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv8hi]; + else + return NULL_TREE; + case CFN_BUILT_IN_BSWAP32: + if (AARCH64_CHECK_BUILTIN_MODE (2, S)) + return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv2si]; + else if (AARCH64_CHECK_BUILTIN_MODE (4, S)) + return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv4si]; + else + return NULL_TREE; + case CFN_BUILT_IN_BSWAP64: + if (AARCH64_CHECK_BUILTIN_MODE (2, D)) + return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv2di]; + else + return NULL_TREE; + default: + return NULL_TREE; } return NULL_TREE; diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 9000d67..e0a050c 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -409,10 +409,7 @@ tree aarch64_builtin_decl (unsigned, bool ATTRIBUTE_UNUSED); tree aarch64_builtin_rsqrt (unsigned int, bool); -tree -aarch64_builtin_vectorized_function (tree fndecl, - tree type_out, - tree type_in); +tree aarch64_builtin_vectorized_function (unsigned int, tree, tree); extern void aarch64_split_combinev16qi (rtx operands[3]); extern void aarch64_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel); diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c index 612ff5c..11cd17d 100644 --- a/gcc/config/arm/arm-builtins.c +++ b/gcc/config/arm/arm-builtins.c @@ -35,6 +35,7 @@ #include "explow.h" #include "expr.h" #include "langhooks.h" +#include "case-cfn-macros.h" #define SIMD_MAX_BUILTIN_ARGS 5 @@ -2842,7 +2843,7 @@ arm_expand_builtin (tree exp, } tree -arm_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in) +arm_builtin_vectorized_function (unsigned int fn, tree type_out, tree type_in) { machine_mode in_mode, out_mode; int in_n, out_n; @@ -2879,19 +2880,16 @@ arm_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in) ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sf, false) \ : NULL_TREE)) - if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) + switch (fn) { - enum built_in_function fn = DECL_FUNCTION_CODE (fndecl); - switch (fn) - { - case BUILT_IN_FLOORF: - return ARM_FIND_VRINT_VARIANT (vrintm); - case BUILT_IN_CEILF: - return ARM_FIND_VRINT_VARIANT (vrintp); - case BUILT_IN_TRUNCF: - return ARM_FIND_VRINT_VARIANT (vrintz); - case BUILT_IN_ROUNDF: - return ARM_FIND_VRINT_VARIANT (vrinta); + CASE_CFN_FLOOR: + return ARM_FIND_VRINT_VARIANT (vrintm); + CASE_CFN_CEIL: + return ARM_FIND_VRINT_VARIANT (vrintp); + CASE_CFN_TRUNC: + return ARM_FIND_VRINT_VARIANT (vrintz); + CASE_CFN_ROUND: + return ARM_FIND_VRINT_VARIANT (vrinta); #undef ARM_CHECK_BUILTIN_MODE_1 #define ARM_CHECK_BUILTIN_MODE_1(C) \ (out_mode == SImode && out_n == C \ @@ -2910,52 +2908,51 @@ arm_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in) : (ARM_CHECK_BUILTIN_MODE (4) \ ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv4sfv4si, false) \ : NULL_TREE)) - case BUILT_IN_LROUNDF: - return out_unsigned_p - ? ARM_FIND_VCVTU_VARIANT (vcvta) - : ARM_FIND_VCVT_VARIANT (vcvta); - case BUILT_IN_LCEILF: - return out_unsigned_p - ? ARM_FIND_VCVTU_VARIANT (vcvtp) - : ARM_FIND_VCVT_VARIANT (vcvtp); - case BUILT_IN_LFLOORF: - return out_unsigned_p - ? ARM_FIND_VCVTU_VARIANT (vcvtm) - : ARM_FIND_VCVT_VARIANT (vcvtm); + CASE_CFN_LROUND: + return (out_unsigned_p + ? ARM_FIND_VCVTU_VARIANT (vcvta) + : ARM_FIND_VCVT_VARIANT (vcvta)); + CASE_CFN_LCEIL: + return (out_unsigned_p + ? ARM_FIND_VCVTU_VARIANT (vcvtp) + : ARM_FIND_VCVT_VARIANT (vcvtp)); + CASE_CFN_LFLOOR: + return (out_unsigned_p + ? ARM_FIND_VCVTU_VARIANT (vcvtm) + : ARM_FIND_VCVT_VARIANT (vcvtm)); #undef ARM_CHECK_BUILTIN_MODE #define ARM_CHECK_BUILTIN_MODE(C, N) \ (out_mode == N##mode && out_n == C \ && in_mode == N##mode && in_n == C) - case BUILT_IN_BSWAP16: - if (ARM_CHECK_BUILTIN_MODE (4, HI)) - return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4hi, false); - else if (ARM_CHECK_BUILTIN_MODE (8, HI)) - return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv8hi, false); - else - return NULL_TREE; - case BUILT_IN_BSWAP32: - if (ARM_CHECK_BUILTIN_MODE (2, SI)) - return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2si, false); - else if (ARM_CHECK_BUILTIN_MODE (4, SI)) - return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4si, false); - else - return NULL_TREE; - case BUILT_IN_BSWAP64: - if (ARM_CHECK_BUILTIN_MODE (2, DI)) - return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2di, false); - else - return NULL_TREE; - case BUILT_IN_COPYSIGNF: - if (ARM_CHECK_BUILTIN_MODE (2, SF)) - return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv2sf, false); - else if (ARM_CHECK_BUILTIN_MODE (4, SF)) - return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv4sf, false); - else - return NULL_TREE; - - default: - return NULL_TREE; - } + case CFN_BUILT_IN_BSWAP16: + if (ARM_CHECK_BUILTIN_MODE (4, HI)) + return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4hi, false); + else if (ARM_CHECK_BUILTIN_MODE (8, HI)) + return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv8hi, false); + else + return NULL_TREE; + case CFN_BUILT_IN_BSWAP32: + if (ARM_CHECK_BUILTIN_MODE (2, SI)) + return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2si, false); + else if (ARM_CHECK_BUILTIN_MODE (4, SI)) + return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4si, false); + else + return NULL_TREE; + case CFN_BUILT_IN_BSWAP64: + if (ARM_CHECK_BUILTIN_MODE (2, DI)) + return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2di, false); + else + return NULL_TREE; + CASE_CFN_COPYSIGN: + if (ARM_CHECK_BUILTIN_MODE (2, SF)) + return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv2sf, false); + else if (ARM_CHECK_BUILTIN_MODE (4, SF)) + return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv4sf, false); + else + return NULL_TREE; + + default: + return NULL_TREE; } return NULL_TREE; } diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 8e73753..e4b8fb3 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -84,7 +84,7 @@ extern char *neon_output_shift_immediate (const char *, char, rtx *, extern void neon_pairwise_reduce (rtx, rtx, machine_mode, rtx (*) (rtx, rtx, rtx)); extern rtx neon_make_constant (rtx); -extern tree arm_builtin_vectorized_function (tree, tree, tree); +extern tree arm_builtin_vectorized_function (unsigned int, tree, tree); extern void neon_expand_vector_init (rtx, rtx); extern void neon_lane_bounds (rtx, HOST_WIDE_INT, HOST_WIDE_INT, const_tree); extern void neon_const_bounds (rtx, HOST_WIDE_INT, HOST_WIDE_INT); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 6173dae..763230a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -73,6 +73,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-chkp.h" #include "rtl-chkp.h" #include "dbgcnt.h" +#include "case-cfn-macros.h" /* This file should be included last. */ #include "target-def.h" @@ -2612,10 +2613,10 @@ static int ix86_tune_defaulted; static int ix86_arch_specified; /* Vectorization library interface and handlers. */ -static tree (*ix86_veclib_handler) (enum built_in_function, tree, tree); +static tree (*ix86_veclib_handler) (combined_fn, tree, tree); -static tree ix86_veclibabi_svml (enum built_in_function, tree, tree); -static tree ix86_veclibabi_acml (enum built_in_function, tree, tree); +static tree ix86_veclibabi_svml (combined_fn, tree, tree); +static tree ix86_veclibabi_acml (combined_fn, tree, tree); /* Processor target table, indexed by processor number */ struct ptt @@ -41989,21 +41990,19 @@ ix86_store_returned_bounds (rtx slot, rtx bounds) emit_move_insn (slot, bounds); } -/* Returns a function decl for a vectorized version of the builtin function - with builtin function code FN and the result vector type TYPE, or NULL_TREE +/* Returns a function decl for a vectorized version of the combined function + with combined_fn code FN and the result vector type TYPE, or NULL_TREE if it is not available. */ static tree -ix86_builtin_vectorized_function (tree fndecl, tree type_out, +ix86_builtin_vectorized_function (unsigned int fn, tree type_out, tree type_in) { machine_mode in_mode, out_mode; int in_n, out_n; - enum built_in_function fn = DECL_FUNCTION_CODE (fndecl); if (TREE_CODE (type_out) != VECTOR_TYPE - || TREE_CODE (type_in) != VECTOR_TYPE - || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL) + || TREE_CODE (type_in) != VECTOR_TYPE) return NULL_TREE; out_mode = TYPE_MODE (TREE_TYPE (type_out)); @@ -42013,7 +42012,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, switch (fn) { - case BUILT_IN_SQRT: + CASE_CFN_SQRT: if (out_mode == DFmode && in_mode == DFmode) { if (out_n == 2 && in_n == 2) @@ -42023,17 +42022,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, else if (out_n == 8 && in_n == 8) return ix86_get_builtin (IX86_BUILTIN_SQRTPD512); } - break; - - case BUILT_IN_EXP2F: - if (out_mode == SFmode && in_mode == SFmode) - { - if (out_n == 16 && in_n == 16) - return ix86_get_builtin (IX86_BUILTIN_EXP2PS); - } - break; - - case BUILT_IN_SQRTF: if (out_mode == SFmode && in_mode == SFmode) { if (out_n == 4 && in_n == 4) @@ -42045,9 +42033,17 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, } break; - case BUILT_IN_IFLOOR: - case BUILT_IN_LFLOOR: - case BUILT_IN_LLFLOOR: + CASE_CFN_EXP2: + if (out_mode == SFmode && in_mode == SFmode) + { + if (out_n == 16 && in_n == 16) + return ix86_get_builtin (IX86_BUILTIN_EXP2PS); + } + break; + + CASE_CFN_IFLOOR: + CASE_CFN_LFLOOR: + CASE_CFN_LLFLOOR: /* The round insn does not trap on denormals. */ if (flag_trapping_math || !TARGET_ROUND) break; @@ -42061,15 +42057,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, else if (out_n == 16 && in_n == 8) return ix86_get_builtin (IX86_BUILTIN_FLOORPD_VEC_PACK_SFIX512); } - break; - - case BUILT_IN_IFLOORF: - case BUILT_IN_LFLOORF: - case BUILT_IN_LLFLOORF: - /* The round insn does not trap on denormals. */ - if (flag_trapping_math || !TARGET_ROUND) - break; - if (out_mode == SImode && in_mode == SFmode) { if (out_n == 4 && in_n == 4) @@ -42079,9 +42066,9 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, } break; - case BUILT_IN_ICEIL: - case BUILT_IN_LCEIL: - case BUILT_IN_LLCEIL: + CASE_CFN_ICEIL: + CASE_CFN_LCEIL: + CASE_CFN_LLCEIL: /* The round insn does not trap on denormals. */ if (flag_trapping_math || !TARGET_ROUND) break; @@ -42095,15 +42082,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, else if (out_n == 16 && in_n == 8) return ix86_get_builtin (IX86_BUILTIN_CEILPD_VEC_PACK_SFIX512); } - break; - - case BUILT_IN_ICEILF: - case BUILT_IN_LCEILF: - case BUILT_IN_LLCEILF: - /* The round insn does not trap on denormals. */ - if (flag_trapping_math || !TARGET_ROUND) - break; - if (out_mode == SImode && in_mode == SFmode) { if (out_n == 4 && in_n == 4) @@ -42113,9 +42091,9 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, } break; - case BUILT_IN_IRINT: - case BUILT_IN_LRINT: - case BUILT_IN_LLRINT: + CASE_CFN_IRINT: + CASE_CFN_LRINT: + CASE_CFN_LLRINT: if (out_mode == SImode && in_mode == DFmode) { if (out_n == 4 && in_n == 2) @@ -42123,11 +42101,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, else if (out_n == 8 && in_n == 4) return ix86_get_builtin (IX86_BUILTIN_VEC_PACK_SFIX256); } - break; - - case BUILT_IN_IRINTF: - case BUILT_IN_LRINTF: - case BUILT_IN_LLRINTF: if (out_mode == SImode && in_mode == SFmode) { if (out_n == 4 && in_n == 4) @@ -42137,9 +42110,9 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, } break; - case BUILT_IN_IROUND: - case BUILT_IN_LROUND: - case BUILT_IN_LLROUND: + CASE_CFN_IROUND: + CASE_CFN_LROUND: + CASE_CFN_LLROUND: /* The round insn does not trap on denormals. */ if (flag_trapping_math || !TARGET_ROUND) break; @@ -42153,15 +42126,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, else if (out_n == 16 && in_n == 8) return ix86_get_builtin (IX86_BUILTIN_ROUNDPD_AZ_VEC_PACK_SFIX512); } - break; - - case BUILT_IN_IROUNDF: - case BUILT_IN_LROUNDF: - case BUILT_IN_LLROUNDF: - /* The round insn does not trap on denormals. */ - if (flag_trapping_math || !TARGET_ROUND) - break; - if (out_mode == SImode && in_mode == SFmode) { if (out_n == 4 && in_n == 4) @@ -42171,7 +42135,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, } break; - case BUILT_IN_COPYSIGN: + CASE_CFN_COPYSIGN: if (out_mode == DFmode && in_mode == DFmode) { if (out_n == 2 && in_n == 2) @@ -42181,9 +42145,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, else if (out_n == 8 && in_n == 8) return ix86_get_builtin (IX86_BUILTIN_CPYSGNPD512); } - break; - - case BUILT_IN_COPYSIGNF: if (out_mode == SFmode && in_mode == SFmode) { if (out_n == 4 && in_n == 4) @@ -42195,7 +42156,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, } break; - case BUILT_IN_FLOOR: + CASE_CFN_FLOOR: /* The round insn does not trap on denormals. */ if (flag_trapping_math || !TARGET_ROUND) break; @@ -42207,13 +42168,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, else if (out_n == 4 && in_n == 4) return ix86_get_builtin (IX86_BUILTIN_FLOORPD256); } - break; - - case BUILT_IN_FLOORF: - /* The round insn does not trap on denormals. */ - if (flag_trapping_math || !TARGET_ROUND) - break; - if (out_mode == SFmode && in_mode == SFmode) { if (out_n == 4 && in_n == 4) @@ -42223,7 +42177,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, } break; - case BUILT_IN_CEIL: + CASE_CFN_CEIL: /* The round insn does not trap on denormals. */ if (flag_trapping_math || !TARGET_ROUND) break; @@ -42235,13 +42189,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, else if (out_n == 4 && in_n == 4) return ix86_get_builtin (IX86_BUILTIN_CEILPD256); } - break; - - case BUILT_IN_CEILF: - /* The round insn does not trap on denormals. */ - if (flag_trapping_math || !TARGET_ROUND) - break; - if (out_mode == SFmode && in_mode == SFmode) { if (out_n == 4 && in_n == 4) @@ -42251,7 +42198,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, } break; - case BUILT_IN_TRUNC: + CASE_CFN_TRUNC: /* The round insn does not trap on denormals. */ if (flag_trapping_math || !TARGET_ROUND) break; @@ -42263,13 +42210,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, else if (out_n == 4 && in_n == 4) return ix86_get_builtin (IX86_BUILTIN_TRUNCPD256); } - break; - - case BUILT_IN_TRUNCF: - /* The round insn does not trap on denormals. */ - if (flag_trapping_math || !TARGET_ROUND) - break; - if (out_mode == SFmode && in_mode == SFmode) { if (out_n == 4 && in_n == 4) @@ -42279,7 +42219,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, } break; - case BUILT_IN_RINT: + CASE_CFN_RINT: /* The round insn does not trap on denormals. */ if (flag_trapping_math || !TARGET_ROUND) break; @@ -42291,13 +42231,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, else if (out_n == 4 && in_n == 4) return ix86_get_builtin (IX86_BUILTIN_RINTPD256); } - break; - - case BUILT_IN_RINTF: - /* The round insn does not trap on denormals. */ - if (flag_trapping_math || !TARGET_ROUND) - break; - if (out_mode == SFmode && in_mode == SFmode) { if (out_n == 4 && in_n == 4) @@ -42307,7 +42240,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, } break; - case BUILT_IN_ROUND: + CASE_CFN_ROUND: /* The round insn does not trap on denormals. */ if (flag_trapping_math || !TARGET_ROUND) break; @@ -42319,13 +42252,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, else if (out_n == 4 && in_n == 4) return ix86_get_builtin (IX86_BUILTIN_ROUNDPD_AZ256); } - break; - - case BUILT_IN_ROUNDF: - /* The round insn does not trap on denormals. */ - if (flag_trapping_math || !TARGET_ROUND) - break; - if (out_mode == SFmode && in_mode == SFmode) { if (out_n == 4 && in_n == 4) @@ -42335,7 +42261,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, } break; - case BUILT_IN_FMA: + CASE_CFN_FMA: if (out_mode == DFmode && in_mode == DFmode) { if (out_n == 2 && in_n == 2) @@ -42343,9 +42269,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, if (out_n == 4 && in_n == 4) return ix86_get_builtin (IX86_BUILTIN_VFMADDPD256); } - break; - - case BUILT_IN_FMAF: if (out_mode == SFmode && in_mode == SFmode) { if (out_n == 4 && in_n == 4) @@ -42361,8 +42284,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, /* Dispatch to a handler for a vectorization library. */ if (ix86_veclib_handler) - return ix86_veclib_handler ((enum built_in_function) fn, type_out, - type_in); + return ix86_veclib_handler (combined_fn (fn), type_out, type_in); return NULL_TREE; } @@ -42371,7 +42293,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out, a library with vectorized intrinsics. */ static tree -ix86_veclibabi_svml (enum built_in_function fn, tree type_out, tree type_in) +ix86_veclibabi_svml (combined_fn fn, tree type_out, tree type_in) { char name[20]; tree fntype, new_fndecl, args; @@ -42394,47 +42316,26 @@ ix86_veclibabi_svml (enum built_in_function fn, tree type_out, tree type_in) switch (fn) { - case BUILT_IN_EXP: - case BUILT_IN_LOG: - case BUILT_IN_LOG10: - case BUILT_IN_POW: - case BUILT_IN_TANH: - case BUILT_IN_TAN: - case BUILT_IN_ATAN: - case BUILT_IN_ATAN2: - case BUILT_IN_ATANH: - case BUILT_IN_CBRT: - case BUILT_IN_SINH: - case BUILT_IN_SIN: - case BUILT_IN_ASINH: - case BUILT_IN_ASIN: - case BUILT_IN_COSH: - case BUILT_IN_COS: - case BUILT_IN_ACOSH: - case BUILT_IN_ACOS: - if (el_mode != DFmode || n != 2) - return NULL_TREE; - break; - - case BUILT_IN_EXPF: - case BUILT_IN_LOGF: - case BUILT_IN_LOG10F: - case BUILT_IN_POWF: - case BUILT_IN_TANHF: - case BUILT_IN_TANF: - case BUILT_IN_ATANF: - case BUILT_IN_ATAN2F: - case BUILT_IN_ATANHF: - case BUILT_IN_CBRTF: - case BUILT_IN_SINHF: - case BUILT_IN_SINF: - case BUILT_IN_ASINHF: - case BUILT_IN_ASINF: - case BUILT_IN_COSHF: - case BUILT_IN_COSF: - case BUILT_IN_ACOSHF: - case BUILT_IN_ACOSF: - if (el_mode != SFmode || n != 4) + CASE_CFN_EXP: + CASE_CFN_LOG: + CASE_CFN_LOG10: + CASE_CFN_POW: + CASE_CFN_TANH: + CASE_CFN_TAN: + CASE_CFN_ATAN: + CASE_CFN_ATAN2: + CASE_CFN_ATANH: + CASE_CFN_CBRT: + CASE_CFN_SINH: + CASE_CFN_SIN: + CASE_CFN_ASINH: + CASE_CFN_ASIN: + CASE_CFN_COSH: + CASE_CFN_COS: + CASE_CFN_ACOSH: + CASE_CFN_ACOS: + if ((el_mode != DFmode || n != 2) + && (el_mode != SFmode || n != 4)) return NULL_TREE; break; @@ -42442,11 +42343,12 @@ ix86_veclibabi_svml (enum built_in_function fn, tree type_out, tree type_in) return NULL_TREE; } - bname = IDENTIFIER_POINTER (DECL_NAME (builtin_decl_implicit (fn))); + tree fndecl = mathfn_built_in (TREE_TYPE (type_in), fn); + bname = IDENTIFIER_POINTER (DECL_NAME (fndecl)); - if (fn == BUILT_IN_LOGF) + if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LOGF) strcpy (name, "vmlsLn4"); - else if (fn == BUILT_IN_LOG) + else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LOG) strcpy (name, "vmldLn2"); else if (n == 4) { @@ -42460,9 +42362,7 @@ ix86_veclibabi_svml (enum built_in_function fn, tree type_out, tree type_in) name[4] &= ~0x20; arity = 0; - for (args = DECL_ARGUMENTS (builtin_decl_implicit (fn)); - args; - args = TREE_CHAIN (args)) + for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args)) arity++; if (arity == 1) @@ -42485,7 +42385,7 @@ ix86_veclibabi_svml (enum built_in_function fn, tree type_out, tree type_in) a library with vectorized intrinsics. */ static tree -ix86_veclibabi_acml (enum built_in_function fn, tree type_out, tree type_in) +ix86_veclibabi_acml (combined_fn fn, tree type_out, tree type_in) { char name[20] = "__vr.._"; tree fntype, new_fndecl, args; @@ -42511,30 +42411,23 @@ ix86_veclibabi_acml (enum built_in_function fn, tree type_out, tree type_in) switch (fn) { - case BUILT_IN_SIN: - case BUILT_IN_COS: - case BUILT_IN_EXP: - case BUILT_IN_LOG: - case BUILT_IN_LOG2: - case BUILT_IN_LOG10: - name[4] = 'd'; - name[5] = '2'; - if (el_mode != DFmode - || n != 2) - return NULL_TREE; - break; - - case BUILT_IN_SINF: - case BUILT_IN_COSF: - case BUILT_IN_EXPF: - case BUILT_IN_POWF: - case BUILT_IN_LOGF: - case BUILT_IN_LOG2F: - case BUILT_IN_LOG10F: - name[4] = 's'; - name[5] = '4'; - if (el_mode != SFmode - || n != 4) + CASE_CFN_SIN: + CASE_CFN_COS: + CASE_CFN_EXP: + CASE_CFN_LOG: + CASE_CFN_LOG2: + CASE_CFN_LOG10: + if (el_mode == DFmode && n == 2) + { + name[4] = 'd'; + name[5] = '2'; + } + else if (el_mode == SFmode && n == 4) + { + name[4] = 's'; + name[5] = '4'; + } + else return NULL_TREE; break; @@ -42542,13 +42435,12 @@ ix86_veclibabi_acml (enum built_in_function fn, tree type_out, tree type_in) return NULL_TREE; } - bname = IDENTIFIER_POINTER (DECL_NAME (builtin_decl_implicit (fn))); + tree fndecl = mathfn_built_in (TREE_TYPE (type_in), fn); + bname = IDENTIFIER_POINTER (DECL_NAME (fndecl)); sprintf (name + 7, "%s", bname+10); arity = 0; - for (args = DECL_ARGUMENTS (builtin_decl_implicit (fn)); - args; - args = TREE_CHAIN (args)) + for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args)) arity++; if (arity == 1) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 5d0a022..688f1db 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -70,6 +70,7 @@ #if TARGET_MACHO #include "gstab.h" /* for N_SLINE */ #endif +#include "case-cfn-macros.h" /* This file should be included last. */ #include "target-def.h" @@ -1107,7 +1108,7 @@ static const struct rs6000_builtin_info_type rs6000_builtin_info[] = #undef RS6000_BUILTIN_X /* Support for -mveclibabi= to control which vector library to use. */ -static tree (*rs6000_veclib_handler) (tree, tree, tree); +static tree (*rs6000_veclib_handler) (combined_fn, tree, tree); static bool rs6000_debug_legitimate_address_p (machine_mode, rtx, bool); @@ -1117,7 +1118,7 @@ static int rs6000_ra_ever_killed (void); static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *); static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *); static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *); -static tree rs6000_builtin_vectorized_libmass (tree, tree, tree); +static tree rs6000_builtin_vectorized_libmass (combined_fn, tree, tree); static void rs6000_emit_set_long_const (rtx, HOST_WIDE_INT); static int rs6000_memory_move_cost (machine_mode, reg_class_t, bool); static bool rs6000_debug_rtx_costs (rtx, machine_mode, int, int, int *, bool); @@ -1606,6 +1607,10 @@ static const struct attribute_spec rs6000_attribute_table[] = #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \ rs6000_builtin_vectorized_function +#undef TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION +#define TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION \ + rs6000_builtin_md_vectorized_function + #if !TARGET_MACHO #undef TARGET_STACK_PROTECT_FAIL #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail @@ -5173,7 +5178,8 @@ rs6000_destroy_cost_data (void *data) library with vectorized intrinsics. */ static tree -rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in) +rs6000_builtin_vectorized_libmass (combined_fn fn, tree type_out, + tree type_in) { char name[32]; const char *suffix = NULL; @@ -5198,93 +5204,57 @@ rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in) || n != in_n) return NULL_TREE; - if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) - { - enum built_in_function fn = DECL_FUNCTION_CODE (fndecl); - switch (fn) - { - case BUILT_IN_ATAN2: - case BUILT_IN_HYPOT: - case BUILT_IN_POW: - n_args = 2; - /* fall through */ - - case BUILT_IN_ACOS: - case BUILT_IN_ACOSH: - case BUILT_IN_ASIN: - case BUILT_IN_ASINH: - case BUILT_IN_ATAN: - case BUILT_IN_ATANH: - case BUILT_IN_CBRT: - case BUILT_IN_COS: - case BUILT_IN_COSH: - case BUILT_IN_ERF: - case BUILT_IN_ERFC: - case BUILT_IN_EXP2: - case BUILT_IN_EXP: - case BUILT_IN_EXPM1: - case BUILT_IN_LGAMMA: - case BUILT_IN_LOG10: - case BUILT_IN_LOG1P: - case BUILT_IN_LOG2: - case BUILT_IN_LOG: - case BUILT_IN_SIN: - case BUILT_IN_SINH: - case BUILT_IN_SQRT: - case BUILT_IN_TAN: - case BUILT_IN_TANH: - bdecl = builtin_decl_implicit (fn); - suffix = "d2"; /* pow -> powd2 */ - if (el_mode != DFmode - || n != 2 - || !bdecl) - return NULL_TREE; - break; + switch (fn) + { + CASE_CFN_ATAN2: + CASE_CFN_HYPOT: + CASE_CFN_POW: + n_args = 2; + /* fall through */ - case BUILT_IN_ATAN2F: - case BUILT_IN_HYPOTF: - case BUILT_IN_POWF: - n_args = 2; - /* fall through */ - - case BUILT_IN_ACOSF: - case BUILT_IN_ACOSHF: - case BUILT_IN_ASINF: - case BUILT_IN_ASINHF: - case BUILT_IN_ATANF: - case BUILT_IN_ATANHF: - case BUILT_IN_CBRTF: - case BUILT_IN_COSF: - case BUILT_IN_COSHF: - case BUILT_IN_ERFF: - case BUILT_IN_ERFCF: - case BUILT_IN_EXP2F: - case BUILT_IN_EXPF: - case BUILT_IN_EXPM1F: - case BUILT_IN_LGAMMAF: - case BUILT_IN_LOG10F: - case BUILT_IN_LOG1PF: - case BUILT_IN_LOG2F: - case BUILT_IN_LOGF: - case BUILT_IN_SINF: - case BUILT_IN_SINHF: - case BUILT_IN_SQRTF: - case BUILT_IN_TANF: - case BUILT_IN_TANHF: - bdecl = builtin_decl_implicit (fn); + CASE_CFN_ACOS: + CASE_CFN_ACOSH: + CASE_CFN_ASIN: + CASE_CFN_ASINH: + CASE_CFN_ATAN: + CASE_CFN_ATANH: + CASE_CFN_CBRT: + CASE_CFN_COS: + CASE_CFN_COSH: + CASE_CFN_ERF: + CASE_CFN_ERFC: + CASE_CFN_EXP2: + CASE_CFN_EXP: + CASE_CFN_EXPM1: + CASE_CFN_LGAMMA: + CASE_CFN_LOG10: + CASE_CFN_LOG1P: + CASE_CFN_LOG2: + CASE_CFN_LOG: + CASE_CFN_SIN: + CASE_CFN_SINH: + CASE_CFN_SQRT: + CASE_CFN_TAN: + CASE_CFN_TANH: + if (el_mode == DFmode && n == 2) + { + bdecl = mathfn_built_in (double_type_node, fn); + suffix = "d2"; /* pow -> powd2 */ + } + else if (el_mode == SFmode && n == 4) + { + bdecl = mathfn_built_in (float_type_node, fn); suffix = "4"; /* powf -> powf4 */ - if (el_mode != SFmode - || n != 4 - || !bdecl) - return NULL_TREE; - break; - - default: - return NULL_TREE; } + else + return NULL_TREE; + if (!bdecl) + return NULL_TREE; + break; + + default: + return NULL_TREE; } - else - return NULL_TREE; gcc_assert (suffix != NULL); bname = IDENTIFIER_POINTER (DECL_NAME (bdecl)); @@ -5317,7 +5287,7 @@ rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in) if it is not available. */ static tree -rs6000_builtin_vectorized_function (tree fndecl, tree type_out, +rs6000_builtin_vectorized_function (unsigned int fn, tree type_out, tree type_in) { machine_mode in_mode, out_mode; @@ -5325,7 +5295,7 @@ rs6000_builtin_vectorized_function (tree fndecl, tree type_out, if (TARGET_DEBUG_BUILTIN) fprintf (stderr, "rs6000_builtin_vectorized_function (%s, %s, %s)\n", - IDENTIFIER_POINTER (DECL_NAME (fndecl)), + combined_fn_name (combined_fn (fn)), GET_MODE_NAME (TYPE_MODE (type_out)), GET_MODE_NAME (TYPE_MODE (type_in))); @@ -5339,203 +5309,205 @@ rs6000_builtin_vectorized_function (tree fndecl, tree type_out, in_mode = TYPE_MODE (TREE_TYPE (type_in)); in_n = TYPE_VECTOR_SUBPARTS (type_in); - if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) + switch (fn) { - enum built_in_function fn = DECL_FUNCTION_CODE (fndecl); - switch (fn) + CASE_CFN_CLZ: + if (TARGET_P8_VECTOR && in_mode == out_mode && out_n == in_n) { - case BUILT_IN_CLZIMAX: - case BUILT_IN_CLZLL: - case BUILT_IN_CLZL: - case BUILT_IN_CLZ: - if (TARGET_P8_VECTOR && in_mode == out_mode && out_n == in_n) - { - if (out_mode == QImode && out_n == 16) - return rs6000_builtin_decls[P8V_BUILTIN_VCLZB]; - else if (out_mode == HImode && out_n == 8) - return rs6000_builtin_decls[P8V_BUILTIN_VCLZH]; - else if (out_mode == SImode && out_n == 4) - return rs6000_builtin_decls[P8V_BUILTIN_VCLZW]; - else if (out_mode == DImode && out_n == 2) - return rs6000_builtin_decls[P8V_BUILTIN_VCLZD]; - } - break; - case BUILT_IN_COPYSIGN: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP]; - break; - case BUILT_IN_COPYSIGNF: - if (out_mode != SFmode || out_n != 4 - || in_mode != SFmode || in_n != 4) - break; - if (VECTOR_UNIT_VSX_P (V4SFmode)) - return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP]; - if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)) - return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF]; - break; - case BUILT_IN_POPCOUNTIMAX: - case BUILT_IN_POPCOUNTLL: - case BUILT_IN_POPCOUNTL: - case BUILT_IN_POPCOUNT: - if (TARGET_P8_VECTOR && in_mode == out_mode && out_n == in_n) - { - if (out_mode == QImode && out_n == 16) - return rs6000_builtin_decls[P8V_BUILTIN_VPOPCNTB]; - else if (out_mode == HImode && out_n == 8) - return rs6000_builtin_decls[P8V_BUILTIN_VPOPCNTH]; - else if (out_mode == SImode && out_n == 4) - return rs6000_builtin_decls[P8V_BUILTIN_VPOPCNTW]; - else if (out_mode == DImode && out_n == 2) - return rs6000_builtin_decls[P8V_BUILTIN_VPOPCNTD]; - } - break; - case BUILT_IN_SQRT: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP]; - break; - case BUILT_IN_SQRTF: - if (VECTOR_UNIT_VSX_P (V4SFmode) - && out_mode == SFmode && out_n == 4 - && in_mode == SFmode && in_n == 4) - return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP]; - break; - case BUILT_IN_CEIL: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP]; - break; - case BUILT_IN_CEILF: - if (out_mode != SFmode || out_n != 4 - || in_mode != SFmode || in_n != 4) - break; - if (VECTOR_UNIT_VSX_P (V4SFmode)) - return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP]; - if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)) - return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP]; - break; - case BUILT_IN_FLOOR: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM]; - break; - case BUILT_IN_FLOORF: - if (out_mode != SFmode || out_n != 4 - || in_mode != SFmode || in_n != 4) - break; - if (VECTOR_UNIT_VSX_P (V4SFmode)) - return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM]; - if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)) - return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM]; - break; - case BUILT_IN_FMA: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP]; - break; - case BUILT_IN_FMAF: - if (VECTOR_UNIT_VSX_P (V4SFmode) - && out_mode == SFmode && out_n == 4 - && in_mode == SFmode && in_n == 4) - return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP]; - else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode) - && out_mode == SFmode && out_n == 4 - && in_mode == SFmode && in_n == 4) - return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP]; - break; - case BUILT_IN_TRUNC: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ]; - break; - case BUILT_IN_TRUNCF: - if (out_mode != SFmode || out_n != 4 - || in_mode != SFmode || in_n != 4) - break; - if (VECTOR_UNIT_VSX_P (V4SFmode)) - return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ]; - if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)) - return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ]; - break; - case BUILT_IN_NEARBYINT: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && flag_unsafe_math_optimizations - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI]; - break; - case BUILT_IN_NEARBYINTF: - if (VECTOR_UNIT_VSX_P (V4SFmode) - && flag_unsafe_math_optimizations - && out_mode == SFmode && out_n == 4 - && in_mode == SFmode && in_n == 4) - return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI]; - break; - case BUILT_IN_RINT: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && !flag_trapping_math - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC]; - break; - case BUILT_IN_RINTF: - if (VECTOR_UNIT_VSX_P (V4SFmode) - && !flag_trapping_math - && out_mode == SFmode && out_n == 4 - && in_mode == SFmode && in_n == 4) - return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC]; - break; - default: - break; + if (out_mode == QImode && out_n == 16) + return rs6000_builtin_decls[P8V_BUILTIN_VCLZB]; + else if (out_mode == HImode && out_n == 8) + return rs6000_builtin_decls[P8V_BUILTIN_VCLZH]; + else if (out_mode == SImode && out_n == 4) + return rs6000_builtin_decls[P8V_BUILTIN_VCLZW]; + else if (out_mode == DImode && out_n == 2) + return rs6000_builtin_decls[P8V_BUILTIN_VCLZD]; } - } - - else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) - { - enum rs6000_builtins fn - = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl); - switch (fn) - { - case RS6000_BUILTIN_RSQRTF: - if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode) - && out_mode == SFmode && out_n == 4 - && in_mode == SFmode && in_n == 4) - return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP]; - break; - case RS6000_BUILTIN_RSQRT: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_RSQRT_2DF]; - break; - case RS6000_BUILTIN_RECIPF: - if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode) - && out_mode == SFmode && out_n == 4 - && in_mode == SFmode && in_n == 4) - return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP]; - break; - case RS6000_BUILTIN_RECIP: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF]; - break; - default: - break; + break; + CASE_CFN_COPYSIGN: + if (VECTOR_UNIT_VSX_P (V2DFmode) + && out_mode == DFmode && out_n == 2 + && in_mode == DFmode && in_n == 2) + return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP]; + if (VECTOR_UNIT_VSX_P (V4SFmode) + && out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP]; + if (VECTOR_UNIT_ALTIVEC_P (V4SFmode) + && out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF]; + break; + CASE_CFN_POPCOUNT: + if (TARGET_P8_VECTOR && in_mode == out_mode && out_n == in_n) + { + if (out_mode == QImode && out_n == 16) + return rs6000_builtin_decls[P8V_BUILTIN_VPOPCNTB]; + else if (out_mode == HImode && out_n == 8) + return rs6000_builtin_decls[P8V_BUILTIN_VPOPCNTH]; + else if (out_mode == SImode && out_n == 4) + return rs6000_builtin_decls[P8V_BUILTIN_VPOPCNTW]; + else if (out_mode == DImode && out_n == 2) + return rs6000_builtin_decls[P8V_BUILTIN_VPOPCNTD]; } + break; + CASE_CFN_SQRT: + if (VECTOR_UNIT_VSX_P (V2DFmode) + && out_mode == DFmode && out_n == 2 + && in_mode == DFmode && in_n == 2) + return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP]; + if (VECTOR_UNIT_VSX_P (V4SFmode) + && out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP]; + break; + CASE_CFN_CEIL: + if (VECTOR_UNIT_VSX_P (V2DFmode) + && out_mode == DFmode && out_n == 2 + && in_mode == DFmode && in_n == 2) + return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP]; + if (VECTOR_UNIT_VSX_P (V4SFmode) + && out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP]; + if (VECTOR_UNIT_ALTIVEC_P (V4SFmode) + && out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP]; + break; + CASE_CFN_FLOOR: + if (VECTOR_UNIT_VSX_P (V2DFmode) + && out_mode == DFmode && out_n == 2 + && in_mode == DFmode && in_n == 2) + return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM]; + if (VECTOR_UNIT_VSX_P (V4SFmode) + && out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM]; + if (VECTOR_UNIT_ALTIVEC_P (V4SFmode) + && out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM]; + break; + CASE_CFN_FMA: + if (VECTOR_UNIT_VSX_P (V2DFmode) + && out_mode == DFmode && out_n == 2 + && in_mode == DFmode && in_n == 2) + return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP]; + if (VECTOR_UNIT_VSX_P (V4SFmode) + && out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP]; + if (VECTOR_UNIT_ALTIVEC_P (V4SFmode) + && out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP]; + break; + CASE_CFN_TRUNC: + if (VECTOR_UNIT_VSX_P (V2DFmode) + && out_mode == DFmode && out_n == 2 + && in_mode == DFmode && in_n == 2) + return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ]; + if (VECTOR_UNIT_VSX_P (V4SFmode) + && out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ]; + if (VECTOR_UNIT_ALTIVEC_P (V4SFmode) + && out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ]; + break; + CASE_CFN_NEARBYINT: + if (VECTOR_UNIT_VSX_P (V2DFmode) + && flag_unsafe_math_optimizations + && out_mode == DFmode && out_n == 2 + && in_mode == DFmode && in_n == 2) + return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI]; + if (VECTOR_UNIT_VSX_P (V4SFmode) + && flag_unsafe_math_optimizations + && out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI]; + break; + CASE_CFN_RINT: + if (VECTOR_UNIT_VSX_P (V2DFmode) + && !flag_trapping_math + && out_mode == DFmode && out_n == 2 + && in_mode == DFmode && in_n == 2) + return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC]; + if (VECTOR_UNIT_VSX_P (V4SFmode) + && !flag_trapping_math + && out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC]; + break; + default: + break; } /* Generate calls to libmass if appropriate. */ if (rs6000_veclib_handler) - return rs6000_veclib_handler (fndecl, type_out, type_in); + return rs6000_veclib_handler (combined_fn (fn), type_out, type_in); + + return NULL_TREE; +} + +/* Implement TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION. */ +static tree +rs6000_builtin_md_vectorized_function (tree fndecl, tree type_out, + tree type_in) +{ + machine_mode in_mode, out_mode; + int in_n, out_n; + + if (TARGET_DEBUG_BUILTIN) + fprintf (stderr, "rs6000_builtin_md_vectorized_function (%s, %s, %s)\n", + IDENTIFIER_POINTER (DECL_NAME (fndecl)), + GET_MODE_NAME (TYPE_MODE (type_out)), + GET_MODE_NAME (TYPE_MODE (type_in))); + + if (TREE_CODE (type_out) != VECTOR_TYPE + || TREE_CODE (type_in) != VECTOR_TYPE + || !TARGET_VECTORIZE_BUILTINS) + return NULL_TREE; + + out_mode = TYPE_MODE (TREE_TYPE (type_out)); + out_n = TYPE_VECTOR_SUBPARTS (type_out); + in_mode = TYPE_MODE (TREE_TYPE (type_in)); + in_n = TYPE_VECTOR_SUBPARTS (type_in); + + enum rs6000_builtins fn + = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl); + switch (fn) + { + case RS6000_BUILTIN_RSQRTF: + if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode) + && out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP]; + break; + case RS6000_BUILTIN_RSQRT: + if (VECTOR_UNIT_VSX_P (V2DFmode) + && out_mode == DFmode && out_n == 2 + && in_mode == DFmode && in_n == 2) + return rs6000_builtin_decls[VSX_BUILTIN_RSQRT_2DF]; + break; + case RS6000_BUILTIN_RECIPF: + if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode) + && out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP]; + break; + case RS6000_BUILTIN_RECIP: + if (VECTOR_UNIT_VSX_P (V2DFmode) + && out_mode == DFmode && out_n == 2 + && in_mode == DFmode && in_n == 2) + return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF]; + break; + default: + break; + } return NULL_TREE; } diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 1a7760a..bde808b 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -5673,11 +5673,17 @@ If this hook is defined, the autovectorizer will use the conversion. Otherwise, it will return @code{NULL_TREE}. @end deftypefn -@deftypefn {Target Hook} tree TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION (tree @var{fndecl}, tree @var{vec_type_out}, tree @var{vec_type_in}) +@deftypefn {Target Hook} tree TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION (unsigned @var{code}, tree @var{vec_type_out}, tree @var{vec_type_in}) This hook should return the decl of a function that implements the -vectorized variant of the builtin function with builtin function code +vectorized variant of the function with the @code{combined_fn} code @var{code} or @code{NULL_TREE} if such a function is not available. -The value of @var{fndecl} is the builtin function declaration. The +The return type of the vectorized function shall be of vector type +@var{vec_type_out} and the argument types should be @var{vec_type_in}. +@end deftypefn + +@deftypefn {Target Hook} tree TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION (tree @var{fndecl}, tree @var{vec_type_out}, tree @var{vec_type_in}) +This hook should return the decl of a function that implements the +vectorized variant of target built-in function @code{fndecl}. The return type of the vectorized function shall be of vector type @var{vec_type_out} and the argument types should be @var{vec_type_in}. @end deftypefn diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 34105c9..0677fc1 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -4235,6 +4235,8 @@ address; but often a machine-dependent strategy can generate better code. @hook TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION +@hook TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION + @hook TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT @hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE diff --git a/gcc/target.def b/gcc/target.def index 61cb14b..b0ad09e 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -1728,18 +1728,28 @@ the argument @var{OFF} to @code{REALIGN_LOAD}, in which case the low\n\ log2(@var{VS}) @minus{} 1 bits of @var{addr} will be considered.", tree, (void), NULL) -/* Returns a code for builtin that realizes vectorized version of - function, or NULL_TREE if not available. */ +/* Returns a built-in function that realizes the vectorized version of + a target-independent function, or NULL_TREE if not available. */ DEFHOOK (builtin_vectorized_function, "This hook should return the decl of a function that implements the\n\ -vectorized variant of the builtin function with builtin function code\n\ +vectorized variant of the function with the @code{combined_fn} code\n\ @var{code} or @code{NULL_TREE} if such a function is not available.\n\ -The value of @var{fndecl} is the builtin function declaration. The\n\ +The return type of the vectorized function shall be of vector type\n\ +@var{vec_type_out} and the argument types should be @var{vec_type_in}.", + tree, (unsigned code, tree vec_type_out, tree vec_type_in), + default_builtin_vectorized_function) + +/* Returns a built-in function that realizes the vectorized version of + a target-specific function, or NULL_TREE if not available. */ +DEFHOOK +(builtin_md_vectorized_function, + "This hook should return the decl of a function that implements the\n\ +vectorized variant of target built-in function @code{fndecl}. The\n\ return type of the vectorized function shall be of vector type\n\ @var{vec_type_out} and the argument types should be @var{vec_type_in}.", tree, (tree fndecl, tree vec_type_out, tree vec_type_in), - default_builtin_vectorized_function) + default_builtin_md_vectorized_function) /* Returns a function declaration for a builtin that realizes the vector conversion, or NULL_TREE if not available. */ diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 66d983b..01d3686 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -534,9 +534,15 @@ default_invalid_within_doloop (const rtx_insn *insn) /* Mapping of builtin functions to vectorized variants. */ tree -default_builtin_vectorized_function (tree fndecl ATTRIBUTE_UNUSED, - tree type_out ATTRIBUTE_UNUSED, - tree type_in ATTRIBUTE_UNUSED) +default_builtin_vectorized_function (unsigned int, tree, tree) +{ + return NULL_TREE; +} + +/* Mapping of target builtin functions to vectorized variants. */ + +tree +default_builtin_md_vectorized_function (tree, tree, tree) { return NULL_TREE; } diff --git a/gcc/targhooks.h b/gcc/targhooks.h index c9d745b..f5d04e6 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -83,7 +83,8 @@ extern bool default_has_ifunc_p (void); extern const char * default_invalid_within_doloop (const rtx_insn *); -extern tree default_builtin_vectorized_function (tree, tree, tree); +extern tree default_builtin_vectorized_function (unsigned int, tree, tree); +extern tree default_builtin_md_vectorized_function (tree, tree, tree); extern tree default_builtin_vectorized_conversion (unsigned int, tree, tree); diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 0f64aaf..0a3cac5 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -1648,20 +1648,20 @@ vect_finish_stmt_generation (gimple *stmt, gimple *vec_stmt, tree vectorizable_function (gcall *call, tree vectype_out, tree vectype_in) { - tree fndecl = gimple_call_fndecl (call); - - /* We only handle functions that do not read or clobber memory -- i.e. - const or novops ones. */ - if (!(gimple_call_flags (call) & (ECF_CONST | ECF_NOVOPS))) + /* We only handle functions that do not read or clobber memory. */ + if (gimple_vuse (call)) return NULL_TREE; - if (!fndecl - || TREE_CODE (fndecl) != FUNCTION_DECL - || !DECL_BUILT_IN (fndecl)) - return NULL_TREE; + combined_fn fn = gimple_call_combined_fn (call); + if (fn != CFN_LAST) + return targetm.vectorize.builtin_vectorized_function + (fn, vectype_out, vectype_in); + + if (gimple_call_builtin_p (call, BUILT_IN_MD)) + return targetm.vectorize.builtin_md_vectorized_function + (gimple_call_fndecl (call), vectype_out, vectype_in); - return targetm.vectorize.builtin_vectorized_function (fndecl, vectype_out, - vectype_in); + return NULL_TREE; } -- 2.7.4