https://gcc.gnu.org/g:b44c5956419377d5203332d9f04a9ea2815ed3b8

commit b44c5956419377d5203332d9f04a9ea2815ed3b8
Author: Michael Meissner <[email protected]>
Date:   Tue Sep 15 12:10:46 2026 -0400

    Limit 16-bit floating point to power9 or later.
    
    2026-09-15  Michael Meissner  <[email protected]>
    
    gcc/
    
            * config/rs6000/float16.md (FP16_FLOAT_CONVERT): Rename from
            fp16_float_convert.  Restructure code.
            (extend<FP16_HW:mode><FP16_FLOAT_CONVERT:mode>2): Likewise.
            (trunc<fp16_float_convert:mode><FP16_HW:mode>2): Likewise.
            (float<GPR:mode><FP16_HW:mode>2): Restructure code.
            (floatuns<GPR:mode><FP16_HW:mode>2): Likewise.
            (fix_trunc<FP16_HW:mode><GPR:mode>2): Likewise.
            (fixuns_trunc<FP16_HW:mode><GPR:mode>2): Likewise.
            * config/rs6000/rs6000.cc (rs6000_option_override_internal): Limit
            16-bit floating point to power9 or later.
            (rs6000_scalar_mode_supported_p): Limit 16-bit floating point to
            -mfloat16.

Diff:
---
 gcc/config/rs6000/float16.md | 73 ++++++++++++++++++++++----------------------
 gcc/config/rs6000/rs6000.cc  | 30 +++++++++++-------
 2 files changed, 55 insertions(+), 48 deletions(-)

diff --git a/gcc/config/rs6000/float16.md b/gcc/config/rs6000/float16.md
index 461369b821e6..672effc6d019 100644
--- a/gcc/config/rs6000/float16.md
+++ b/gcc/config/rs6000/float16.md
@@ -36,7 +36,7 @@
 
 ;; Mode iterator for floating point modes other than SF/DFmode that we
 ;; convert to/from _Float16 (HFmode) via DFmode.
-(define_mode_iterator fp16_float_convert [TF KF IF SD DD TD])
+(define_mode_iterator FP16_FLOAT_CONVERT [TF KF IF SD DD TD])
 
 ;; Mode attribute giving the instruction to convert the even
 ;; V8HFmode or V8BFmode elements to V4SFmode
@@ -595,78 +595,77 @@
 ;; types might not have valid RTX expanders.  We use DFmode as the
 ;; intermediate conversion destination.
 
-(define_expand "extend<FP16_HW:mode><fp16_float_convert:mode>2"
-  [(set (match_operand:fp16_float_convert 0 "vsx_register_operand")
-       (float_extend:fp16_float_convert
-        (match_operand:FP16_HW 1 "vsx_register_operand")))]
-  ""
+(define_expand "extend<FP16_HW:mode><FP16_FLOAT_CONVERT:mode>2"
+  [(use (match_operand:FP16_FLOAT_CONVERT 0 "vsx_register_operand"))
+   (use (match_operand:FP16_HW 1 "vsx_register_operand"))]
+  "can_create_pseudo_p ()"
 {
   rtx df_tmp = gen_reg_rtx (DFmode);
-  emit_insn (gen_extend<FP16_HW:mode>df2 (df_tmp, operands[1]));
+
+  convert_move (df_tmp, operands[1], 0);
   convert_move (operands[0], df_tmp, 0);
   DONE;
 })
 
-(define_expand "trunc<fp16_float_convert:mode><FP16_HW:mode>2"
-  [(set (match_operand:FP16_HW 0 "vsx_register_operand")
-       (float_truncate:FP16_HW
-        (match_operand:fp16_float_convert 1 "vsx_register_operand")))]
-  ""
+(define_expand "trunc<FP16_FLOAT_CONVERT:mode><FP16_HW:mode>2"
+  [(use (match_operand:FP16_HW 0 "vsx_register_operand"))
+   (use (match_operand:FP16_FLOAT_CONVERT 1 "vsx_register_operand"))]
+  "can_create_pseudo_p ()"
 {
   rtx df_tmp = gen_reg_rtx (DFmode);
 
   convert_move (df_tmp, operands[1], 0);
-  emit_insn (gen_truncdf<FP16_HW:mode>2 (operands[0], df_tmp));
+  convert_move (operands[0], df_tmp, 0);
   DONE;
 })
 
 ;; Convert integers to 16-bit floating point modes.
 (define_expand "float<GPR:mode><FP16_HW:mode>2"
-  [(set (match_operand:FP16_HW 0 "vsx_register_operand")
-       (float:FP16_HW
-        (match_operand:GPR 1 "vsx_register_operand")))]
-  ""
+  [(use (match_operand:FP16_HW 0 "vsx_register_operand"))
+   (use (match_operand:GPR 1 "vsx_register_operand"))]
+  "can_create_pseudo_p ()"
 {
   rtx df_tmp = gen_reg_rtx (DFmode);
-  emit_insn (gen_float<GPR:mode>df2 (df_tmp, operands[1]));
-  emit_insn (gen_truncdf<FP16_HW:mode>2 (operands[0], df_tmp));
+
+  convert_move (df_tmp, operands[1], 0);
+  convert_move (operands[0], df_tmp, 0);
   DONE;
 })
 
 (define_expand "floatuns<GPR:mode><FP16_HW:mode>2"
-  [(set (match_operand:FP16_HW 0 "vsx_register_operand")
-       (unsigned_float:FP16_HW
-        (match_operand:GPR 1 "vsx_register_operand")))]
-  ""
+  [(use (match_operand:FP16_HW 0 "vsx_register_operand"))
+   (use (match_operand:GPR 1 "vsx_register_operand"))]
+  "can_create_pseudo_p ()"
 {
   rtx df_tmp = gen_reg_rtx (DFmode);
-  emit_insn (gen_floatuns<GPR:mode>df2 (df_tmp, operands[1]));
-  emit_insn (gen_truncdf<FP16_HW:mode>2 (operands[0], df_tmp));
+
+  convert_move (df_tmp, operands[1], 1);
+  convert_move (operands[0], df_tmp, 0);
   DONE;
 })
 
 ;; Convert 16-bit floating point modes to integers
 (define_expand "fix_trunc<FP16_HW:mode><GPR:mode>2"
-  [(set (match_operand:GPR 0 "vsx_register_operand")
-       (fix:GPR
-        (match_operand:FP16_HW 1 "vsx_register_operand")))]
-  ""
+  [(use (match_operand:GPR 0 "vsx_register_operand"))
+   (use (match_operand:FP16_HW 1 "vsx_register_operand"))]
+  "can_create_pseudo_p ()"
 {
   rtx df_tmp = gen_reg_rtx (DFmode);
-  emit_insn (gen_extend<FP16_HW:mode>df2 (df_tmp, operands[1]));
-  emit_insn (gen_fix_truncdf<GPR:mode>2 (operands[0], df_tmp));
+
+  convert_move (df_tmp, operands[1], 0);
+  convert_move (operands[0], df_tmp, 0);
   DONE;
 })
 
 (define_expand "fixuns_trunc<FP16_HW:mode><GPR:mode>2"
-  [(set (match_operand:GPR 0 "vsx_register_operand")
-       (unsigned_fix:GPR
-        (match_operand:FP16_HW 1 "vsx_register_operand")))]
-  ""
+  [(use (match_operand:GPR 0 "vsx_register_operand"))
+   (use (match_operand:FP16_HW 1 "vsx_register_operand"))]
+  "can_create_pseudo_p ()"
 {
   rtx df_tmp = gen_reg_rtx (DFmode);
-  emit_insn (gen_extend<FP16_HW:mode>df2 (df_tmp, operands[1]));
-  emit_insn (gen_fixuns_truncdf<GPR:mode>2 (operands[0], df_tmp));
+
+  convert_move (df_tmp, operands[1], 0);
+  convert_move (operands[0], df_tmp, 1);
   DONE;
 })
 
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 8df2333d5b3a..917cb401f718 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -3994,17 +3994,25 @@ rs6000_option_override_internal (bool global_init_p)
        }
     }
 
-  /* 16-bit floating point needs 64-bit power8 at a minimum in order to load up
-     16-bit values into vector registers via loads/stores from GPRs and then
-     using direct moves.  Don't allow 16-bit float on big endian systems at the
-     current time.  */
-  if (TARGET_FLOAT16 && (!TARGET_DIRECT_MOVE_64BIT || BYTES_BIG_ENDIAN))
+  /* Limit 16-bit floating point to power9 or later in order to load up
+     16-bit values into vector registers via loads/stores from GPRs and
+     then using direct moves.  Don't allow 16-bit float on big endian
+     systems at the current time.  */
+  if (TARGET_FLOAT16)
     {
-      rs6000_isa_flags &= ~OPTION_MASK_FLOAT16;
-      if (rs6000_isa_flags_explicit & OPTION_MASK_FLOAT16)
-       error ("%qs is only available on 64-bit little endian systems "
-              "that use at least %qs",
-              "-mfloat16", "-mcpu=power8");
+      if (!TARGET_P9_VECTOR)
+       {
+         rs6000_isa_flags &= ~OPTION_MASK_FLOAT16;
+         if (rs6000_isa_flags_explicit & OPTION_MASK_FLOAT16)
+           error ("%qs needs at least %qs", "-mfloat16", "-mcpu=power9");
+       }
+      else if (BYTES_BIG_ENDIAN || !TARGET_POWERPC64)
+       {
+         rs6000_isa_flags &= ~OPTION_MASK_FLOAT16;
+         if (rs6000_isa_flags_explicit & OPTION_MASK_FLOAT16)
+           error ("%qs is only available on 64-bit little endian systems",
+                  "-mfloat16");
+       }
     }
 
   /* If hard-float/altivec/vsx were explicitly turned off then don't allow
@@ -24781,7 +24789,7 @@ rs6000_scalar_mode_supported_p (scalar_mode mode)
   else if (TARGET_FLOAT128_TYPE && (mode == KFmode || mode == IFmode))
     return true;
   else if (FP16_SCALAR_MODE_P (mode))
-    return true;
+    return TARGET_FLOAT16;
   else
     return default_scalar_mode_supported_p (mode);
 }

Reply via email to