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;

Reply via email to