https://gcc.gnu.org/g:271b02e72662c0c0e06b35bedfc1581acda8ab83
commit 271b02e72662c0c0e06b35bedfc1581acda8ab83 Author: Michael Meissner <[email protected]> Date: Wed Oct 28 04:21:01 2026 -0400 Vectorize both V4SF to V8BF and V4SF to V8HF narrowing. 2026-10-28 Michael Meissner <[email protected]> * config/rs6000/rs6000.cc (TARGET_VECTORIZE_OTHER_NARROWING_MODE): New hook. (rs6000_vector_other_narrowing_mode): Likewise. * doc/tm.texi: Regenerate. * doc/tm.texi.in (TARGET_VECTORIZE_OTHER_NARROWING_MODE): Document new hook. * target.def (other_narrowing_mode): New target hook. * targhooks.cc (default_vectorize_other_narrowing_mode): Likewise. * targhooks.h (default_vectorize_other_narrowing_mode): Likewise * tree-vect-stmts.cc (supportable_narrowing_operation) Call the vectorize.other_narrowing_mode hook. Diff: --- gcc/config/rs6000/rs6000.cc | 23 +++++++++++++++++++++++ gcc/doc/tm.texi | 10 ++++++++++ gcc/doc/tm.texi.in | 2 ++ gcc/target.def | 14 ++++++++++++++ gcc/targhooks.cc | 6 ++++++ gcc/targhooks.h | 3 ++- gcc/tree-vect-stmts.cc | 10 ++++++++++ 7 files changed, 67 insertions(+), 1 deletion(-) diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 184026f1bee1..220de040cfb6 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -1792,6 +1792,9 @@ static const scoped_attribute_specs *const rs6000_attribute_table[] = #undef TARGET_OVERLAP_OP_BY_PIECES_P #define TARGET_OVERLAP_OP_BY_PIECES_P hook_bool_void_true +#undef TARGET_VECTORIZE_OTHER_NARROWING_MODE +#define TARGET_VECTORIZE_OTHER_NARROWING_MODE \ + rs6000_vector_other_narrowing_mode /* Processor table. */ @@ -30141,6 +30144,26 @@ rs6000_opaque_type_invalid_use_p (gimple *stmt) return false; } +/* There are 2 possible 16-bit floating point formats that a V4SFmode can be + converted to (i.e. V8BFmode and V8HFmode). Unfortunately only one 16-bit + format can be selected via vec_pack_trunc_v4sf. This hook returns true if + we can use the alterntive narrowing method. */ + +bool +rs6000_vector_other_narrowing_mode (machine_mode narrow, machine_mode wide) +{ + if (wide == V4SFmode) + { + if (narrow == V8BFmode && TARGET_BFLOAT16_HW) + return true; + + if (narrow == V8HFmode && TARGET_FLOAT16_HW) + return true; + } + + return false; +} + #undef TARGET_DOCUMENTATION_NAME #define TARGET_DOCUMENTATION_NAME "PowerPC" diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 09512a07a87c..e0450d7e7b20 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -6594,6 +6594,16 @@ number of scalar elements in each scalar loop iteration that are to be combined into the vector. @end deftypefn +@deftypefn {Target Hook} bool TARGET_VECTORIZE_OTHER_NARROWING_MODE (machine_mode @var{narrow}, machine_mode @var{wide}) +Target hook that returns true if there is an alternative way to +perform narrowing operation. For example, on the PowerPC, there are +2 16-bit floating point types (BFmode and HFmode). However, the +named insn @code{vec_pack_trunc_v4sf} can only indicate one vector +machine mode to return. + +This hook returns true if there is an alternative vector type to use. +@end deftypefn + @node OpenMP and OpenACC @section OpenMP and OpenACC @cindex OpenMP and OpenACC diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 9faacb28781d..ea50c182b56d 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -4353,6 +4353,8 @@ address; but often a machine-dependent strategy can generate better code. @hook TARGET_VECTORIZE_PREFER_GATHER_SCATTER +@hook TARGET_VECTORIZE_OTHER_NARROWING_MODE + @node OpenMP and OpenACC @section OpenMP and OpenACC @cindex OpenMP and OpenACC diff --git a/gcc/target.def b/gcc/target.def index 20c7f111295d..1439c0f10f20 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -2113,6 +2113,20 @@ it is for the vector version.", (vec_info *vinfo, bool costing_for_scalar), default_vectorize_create_costs) +/* Whether a vector mode can be narrowed to an alterntive mode. */ +DEFHOOK +(other_narrowing_mode, + "Target hook that returns true if there is an alternative way to\n\ +perform narrowing operation. For example, on the PowerPC, there are\n\ +2 16-bit floating point types (BFmode and HFmode). However, the\n\ +named insn @code{vec_pack_trunc_v4sf} can only indicate one vector\n\ +machine mode to return.\n\ +\n\ +This hook returns true if there is an alternative vector type to use.", + bool, + (machine_mode narrow, machine_mode wide), + default_vector_other_narrowing_mode) + HOOK_VECTOR_END (vectorize) #undef HOOK_PREFIX diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc index 21cbfda48018..2d4dcd472637 100644 --- a/gcc/targhooks.cc +++ b/gcc/targhooks.cc @@ -2999,4 +2999,10 @@ default_reassociation_width (tree_code, machine_mode) return 1; } +bool +default_vectorize_other_narrowing_mode (machine_mode narrow ATTRIBUTE_UNUSED, + machine_mode wide ATTRIBUTE_UNUSED) +{ + return false; +} #include "gt-targhooks.h" diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 4b029bbe4053..dcfbc880b377 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -325,5 +325,6 @@ extern rtx default_memtag_set_tag (rtx, rtx, rtx); extern rtx default_memtag_extract_tag (rtx, rtx); extern rtx default_memtag_untagged_pointer (rtx, rtx); extern int default_reassociation_width (tree_code, machine_mode); - +extern bool default_vectorize_other_narrowing_mode (machine_mode, + machine_mode); #endif /* GCC_TARGHOOKS_H */ diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 38f9ad01e87b..2ac2d64ce4f0 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -14286,6 +14286,16 @@ supportable_narrowing_operation (code_helper code, if (code == FLOAT_EXPR) return false; + /* There might be two different vector types that has a narrow conversion. + For example, on the PowerPC V4SFmode can be narrowed to either V8HFmode + (IEEE 16-bit floating point) or V8BFmode (Google 16-bit brain floating + point). Unfortunately only one of these formats can be selected via + vec_pack_trunc_<xxx>. This patches sees if we can use types + separately. */ + machine_mode narrow_mode = TYPE_MODE (vectype_out); + if (targetm.vectorize.other_narrowing_mode (narrow_mode, vec_mode)) + return true; + /* Check if it's a multi-step conversion that can be done using intermediate types. */ prev_mode = vec_mode;
