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.
I've attached a -b version too since that's easier to read. 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.
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 0f20f60..c77dbbf 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -407,10 +407,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 bad3dc3..ee2e7b0 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 @@ -2812,7 +2813,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; @@ -2849,19 +2850,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 \ @@ -2880,52 +2878,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 f9b1276..10c96b2 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 bb37aba..a1d59a5 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" @@ -2611,10 +2612,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 @@ -41723,21 +41724,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)); @@ -41747,7 +41746,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) @@ -41757,17 +41756,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) @@ -41779,9 +41767,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; @@ -41795,15 +41791,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) @@ -41813,9 +41800,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; @@ -41829,15 +41816,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) @@ -41847,9 +41825,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) @@ -41857,11 +41835,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) @@ -41871,9 +41844,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; @@ -41887,15 +41860,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) @@ -41905,7 +41869,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) @@ -41915,9 +41879,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) @@ -41929,7 +41890,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; @@ -41941,13 +41902,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) @@ -41957,7 +41911,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; @@ -41969,13 +41923,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) @@ -41985,7 +41932,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; @@ -41997,13 +41944,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) @@ -42013,7 +41953,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; @@ -42025,13 +41965,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) @@ -42041,7 +41974,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; @@ -42053,13 +41986,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) @@ -42069,7 +41995,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) @@ -42077,9 +42003,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) @@ -42095,8 +42018,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; } @@ -42105,7 +42027,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; @@ -42128,47 +42050,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; @@ -42176,11 +42077,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) { @@ -42194,9 +42096,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) @@ -42219,7 +42119,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; @@ -42245,30 +42145,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; @@ -42276,13 +42169,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 8bdd646..26a0410 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" @@ -1077,7 +1078,7 @@ static const struct rs6000_builtin_info_type rs6000_builtin_info[] = #undef RS6000_BUILTIN_X /* Support for -mveclibabi=<xxx> 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); @@ -1087,7 +1088,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); @@ -1576,6 +1577,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 @@ -4775,7 +4780,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; @@ -4800,93 +4806,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)); @@ -4919,7 +4889,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; @@ -4927,7 +4897,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))); @@ -4941,203 +4911,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 f394db7..20a77d1 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -5668,11 +5668,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 d188c57..b1c6d1e 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -4230,6 +4230,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 c7ec292..dddbd2c 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 14324b7..7852670 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -533,9 +533,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 a8e7ebb..ea263da 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 51dff9e..75389c4 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -1639,20 +1639,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; }
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,44 +1284,35 @@ 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) - { - 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: + CASE_CFN_FLOOR: return AARCH64_FIND_FRINT_VARIANT (floor); - case BUILT_IN_CEIL: - case BUILT_IN_CEILF: + CASE_CFN_CEIL: return AARCH64_FIND_FRINT_VARIANT (ceil); - case BUILT_IN_TRUNC: - case BUILT_IN_TRUNCF: + CASE_CFN_TRUNC: return AARCH64_FIND_FRINT_VARIANT (btrunc); - case BUILT_IN_ROUND: - case BUILT_IN_ROUNDF: + CASE_CFN_ROUND: return AARCH64_FIND_FRINT_VARIANT (round); - case BUILT_IN_NEARBYINT: - case BUILT_IN_NEARBYINTF: + CASE_CFN_NEARBYINT: return AARCH64_FIND_FRINT_VARIANT (nearbyint); - case BUILT_IN_SQRT: - case BUILT_IN_SQRTF: + 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: + CASE_CFN_CLZ: { if (AARCH64_CHECK_BUILTIN_MODE (4, S)) return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_clzv4si]; return NULL_TREE; } - case BUILT_IN_CTZ: + CASE_CFN_CTZ: { if (AARCH64_CHECK_BUILTIN_MODE (2, S)) return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_ctzv2si]; @@ -1331,10 +1324,9 @@ aarch64_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in) #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: + CASE_CFN_IFLOOR: + CASE_CFN_LFLOOR: + CASE_CFN_LLFLOOR: { enum aarch64_builtins builtin; if (AARCH64_CHECK_BUILTIN_MODE (2, D)) @@ -1348,10 +1340,9 @@ aarch64_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in) return aarch64_builtin_decls[builtin]; } - case BUILT_IN_LCEIL: - case BUILT_IN_LCEILF: - case BUILT_IN_LLCEIL: - case BUILT_IN_ICEILF: + CASE_CFN_ICEIL: + CASE_CFN_LCEIL: + CASE_CFN_LLCEIL: { enum aarch64_builtins builtin; if (AARCH64_CHECK_BUILTIN_MODE (2, D)) @@ -1365,8 +1356,9 @@ aarch64_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in) return aarch64_builtin_decls[builtin]; } - case BUILT_IN_LROUND: - case BUILT_IN_IROUNDF: + CASE_CFN_IROUND: + CASE_CFN_LROUND: + CASE_CFN_LLROUND: { enum aarch64_builtins builtin; if (AARCH64_CHECK_BUILTIN_MODE (2, D)) @@ -1380,7 +1372,7 @@ aarch64_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in) return aarch64_builtin_decls[builtin]; } - case BUILT_IN_BSWAP16: + case CFN_BUILT_IN_BSWAP16: #undef AARCH64_CHECK_BUILTIN_MODE #define AARCH64_CHECK_BUILTIN_MODE(C, N) \ (out_mode == N##Imode && out_n == C \ @@ -1391,14 +1383,14 @@ aarch64_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in) return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv8hi]; else return NULL_TREE; - case BUILT_IN_BSWAP32: + 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 BUILT_IN_BSWAP64: + case CFN_BUILT_IN_BSWAP64: if (AARCH64_CHECK_BUILTIN_MODE (2, D)) return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv2di]; else @@ -1406,7 +1398,6 @@ aarch64_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in) default: return NULL_TREE; } - } return NULL_TREE; } diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 0f20f60..c77dbbf 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -407,10 +407,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 bad3dc3..ee2e7b0 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 @@ -2812,7 +2813,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; @@ -2849,18 +2850,15 @@ 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) - { - enum built_in_function fn = DECL_FUNCTION_CODE (fndecl); switch (fn) { - case BUILT_IN_FLOORF: + CASE_CFN_FLOOR: return ARM_FIND_VRINT_VARIANT (vrintm); - case BUILT_IN_CEILF: + CASE_CFN_CEIL: return ARM_FIND_VRINT_VARIANT (vrintp); - case BUILT_IN_TRUNCF: + CASE_CFN_TRUNC: return ARM_FIND_VRINT_VARIANT (vrintz); - case BUILT_IN_ROUNDF: + CASE_CFN_ROUND: return ARM_FIND_VRINT_VARIANT (vrinta); #undef ARM_CHECK_BUILTIN_MODE_1 #define ARM_CHECK_BUILTIN_MODE_1(C) \ @@ -2880,42 +2878,42 @@ 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 + CASE_CFN_LROUND: + return (out_unsigned_p ? ARM_FIND_VCVTU_VARIANT (vcvta) - : ARM_FIND_VCVT_VARIANT (vcvta); - case BUILT_IN_LCEILF: - return out_unsigned_p + : ARM_FIND_VCVT_VARIANT (vcvta)); + CASE_CFN_LCEIL: + return (out_unsigned_p ? ARM_FIND_VCVTU_VARIANT (vcvtp) - : ARM_FIND_VCVT_VARIANT (vcvtp); - case BUILT_IN_LFLOORF: - return out_unsigned_p + : ARM_FIND_VCVT_VARIANT (vcvtp)); + CASE_CFN_LFLOOR: + return (out_unsigned_p ? ARM_FIND_VCVTU_VARIANT (vcvtm) - : ARM_FIND_VCVT_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: + 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 BUILT_IN_BSWAP32: + 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 BUILT_IN_BSWAP64: + 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 BUILT_IN_COPYSIGNF: + 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)) @@ -2926,7 +2924,6 @@ arm_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in) default: return NULL_TREE; } - } return NULL_TREE; } #undef ARM_FIND_VCVT_VARIANT diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index f9b1276..10c96b2 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 bb37aba..a1d59a5 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" @@ -2611,10 +2612,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 @@ -41723,21 +41724,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)); @@ -41747,7 +41746,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) @@ -41757,17 +41756,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) @@ -41779,9 +41767,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; @@ -41795,15 +41791,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) @@ -41813,9 +41800,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; @@ -41829,15 +41816,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) @@ -41847,9 +41825,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) @@ -41857,11 +41835,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) @@ -41871,9 +41844,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; @@ -41887,15 +41860,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) @@ -41905,7 +41869,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) @@ -41915,9 +41879,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) @@ -41929,7 +41890,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; @@ -41941,13 +41902,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) @@ -41957,7 +41911,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; @@ -41969,13 +41923,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) @@ -41985,7 +41932,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; @@ -41997,13 +41944,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) @@ -42013,7 +41953,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; @@ -42025,13 +41965,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) @@ -42041,7 +41974,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; @@ -42053,13 +41986,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) @@ -42069,7 +41995,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) @@ -42077,9 +42003,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) @@ -42095,8 +42018,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; } @@ -42105,7 +42027,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; @@ -42128,47 +42050,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; @@ -42176,11 +42077,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) { @@ -42194,9 +42096,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) @@ -42219,7 +42119,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; @@ -42245,30 +42145,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: + 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'; - 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: + } + else if (el_mode == SFmode && n == 4) + { name[4] = 's'; name[5] = '4'; - if (el_mode != SFmode - || n != 4) + } + else return NULL_TREE; break; @@ -42276,13 +42169,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 8bdd646..26a0410 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" @@ -1077,7 +1078,7 @@ static const struct rs6000_builtin_info_type rs6000_builtin_info[] = #undef RS6000_BUILTIN_X /* Support for -mveclibabi=<xxx> 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); @@ -1087,7 +1088,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); @@ -1576,6 +1577,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 @@ -4775,7 +4780,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; @@ -4800,93 +4806,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: + CASE_CFN_ATAN2: + CASE_CFN_HYPOT: + CASE_CFN_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); + 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 */ - if (el_mode != DFmode - || n != 2 - || !bdecl) - return NULL_TREE; - break; - - 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); + } + 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) + } + 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)); @@ -4919,7 +4889,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; @@ -4927,7 +4897,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))); @@ -4941,15 +4911,9 @@ 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) - { - enum built_in_function fn = DECL_FUNCTION_CODE (fndecl); switch (fn) { - case BUILT_IN_CLZIMAX: - case BUILT_IN_CLZLL: - case BUILT_IN_CLZL: - case BUILT_IN_CLZ: + CASE_CFN_CLZ: if (TARGET_P8_VECTOR && in_mode == out_mode && out_n == in_n) { if (out_mode == QImode && out_n == 16) @@ -4962,25 +4926,21 @@ rs6000_builtin_vectorized_function (tree fndecl, tree type_out, return rs6000_builtin_decls[P8V_BUILTIN_VCLZD]; } break; - case BUILT_IN_COPYSIGN: + 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]; - 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)) + 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)) + 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 BUILT_IN_POPCOUNTIMAX: - case BUILT_IN_POPCOUNTLL: - case BUILT_IN_POPCOUNTL: - case BUILT_IN_POPCOUNT: + CASE_CFN_POPCOUNT: if (TARGET_P8_VECTOR && in_mode == out_mode && out_n == in_n) { if (out_mode == QImode && out_n == 16) @@ -4993,101 +4953,90 @@ rs6000_builtin_vectorized_function (tree fndecl, tree type_out, return rs6000_builtin_decls[P8V_BUILTIN_VPOPCNTD]; } break; - case BUILT_IN_SQRT: + 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]; - 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: + 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]; - 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)) + 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)) + 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 BUILT_IN_FLOOR: + 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]; - 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)) + 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)) + 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 BUILT_IN_FMA: + 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]; - 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) + 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: + 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]; - 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)) + 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)) + 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 BUILT_IN_NEARBYINT: + 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]; - 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: + 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]; - break; - case BUILT_IN_RINTF: if (VECTOR_UNIT_VSX_P (V4SFmode) && !flag_trapping_math && out_mode == SFmode && out_n == 4 @@ -5097,12 +5046,41 @@ rs6000_builtin_vectorized_function (tree fndecl, tree type_out, default: break; } - } - else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) - { + /* Generate calls to libmass if appropriate. */ + if (rs6000_veclib_handler) + 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); + = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl); switch (fn) { case RS6000_BUILTIN_RSQRTF: @@ -5132,12 +5110,6 @@ rs6000_builtin_vectorized_function (tree fndecl, tree type_out, default: break; } - } - - /* Generate calls to libmass if appropriate. */ - if (rs6000_veclib_handler) - return rs6000_veclib_handler (fndecl, type_out, type_in); - return NULL_TREE; } diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index f394db7..20a77d1 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -5668,11 +5668,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 d188c57..b1c6d1e 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -4230,6 +4230,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 c7ec292..dddbd2c 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 14324b7..7852670 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -533,9 +533,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 a8e7ebb..ea263da 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 51dff9e..75389c4 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -1639,20 +1639,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); - return targetm.vectorize.builtin_vectorized_function (fndecl, 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 NULL_TREE; }