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

commit dfa4629b83cfdd161b11f0d183b38b671bd6916e
Author: Michael Meissner <meiss...@linux.ibm.com>
Date:   Thu Aug 14 02:19:17 2025 -0400

    Pass _Float16 arguments and return values in GPRs
    
    2025-08-14  Michael Meissner  <meiss...@linux.ibm.com>
    
    gcc/
    
            PR target/121525
            * config/rs6000/rs6000-call.cc (USE_FP_FOR_ARG_P): Don't pass 
_Float16
            arguments in vector registers unless -mieee16-gpr-args.
            (rs6000_return_in_memory): Remove previous code possibly returning
            _Float16 values in memory and passing arguments in memory.
            (rs6000_pass_by_reference): Likewise.
            (rs6000_function_value): Return _Float16 values in GPRs unless
            -mno-ieee16-gpr-args is used.
            * config/rs6000/rs6000.cc (rs6000_function_value): Return _Float16
            variables in GPRs unless -mno-ieee16-gpr-args.
            * config/rs6000/rs6000.md (movhf_xxspltiw): Add support for loading
            _Float16 constants in GPRs.
            * config/rs6000/rs6000.opt (-mieee16-return-in-memory): Delete.
            (-mieee16-pass-by-reference): Likewise.
            (-mieee16-gpr-args): New options.

Diff:
---
 gcc/config/rs6000/rs6000-call.cc | 20 ++++++--------------
 gcc/config/rs6000/rs6000.cc      |  2 ++
 gcc/config/rs6000/rs6000.md      | 14 ++++++++------
 gcc/config/rs6000/rs6000.opt     | 10 +++-------
 4 files changed, 19 insertions(+), 27 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-call.cc b/gcc/config/rs6000/rs6000-call.cc
index d639519a4368..3872d742d159 100644
--- a/gcc/config/rs6000/rs6000-call.cc
+++ b/gcc/config/rs6000/rs6000-call.cc
@@ -82,10 +82,12 @@
 #endif
 
 /* Nonzero if we can use a floating-point register to pass this arg.  */
-#define USE_FP_FOR_ARG_P(CUM,MODE)             \
-  (SCALAR_FLOAT_MODE_NOT_VECTOR_P (MODE)               \
-   && (CUM)->fregno <= FP_ARG_MAX_REG          \
-   && TARGET_HARD_FLOAT)
+#define USE_FP_FOR_ARG_P(CUM,MODE)                             \
+  (SCALAR_FLOAT_MODE_NOT_VECTOR_P (MODE)                       \
+   && (CUM)->fregno <= FP_ARG_MAX_REG                          \
+   && TARGET_HARD_FLOAT                                                \
+   && ((MODE) != HFmode || !TARGET_IEEE16_GPR_ARGS))
+
 
 /* Nonzero if we can use an AltiVec register to pass this arg.  */
 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,NAMED)                  \
@@ -432,11 +434,6 @@ rs6000_discover_homogeneous_aggregate (machine_mode mode, 
const_tree type,
 bool
 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
 {
-  /* Because it is not covered by the ABI, return _Float16 (HFmode) in
-     memory.  */
-  if (TYPE_MODE (type) == HFmode && TARGET_IEEE16_RETURN_IN_MEMORY)
-    return true;
-
   /* We do not allow MMA types being used as return values.  Only report
      the invalid return value usage the first time we encounter it.  */
   if (cfun
@@ -1990,11 +1987,6 @@ rs6000_pass_by_reference (cumulative_args_t, const 
function_arg_info &arg)
   if (!arg.type)
     return 0;
 
-  /* Because it is not covered by the ABI, pass _Float16 (HFmode) by
-     reference.  */
-  if (arg.mode == HFmode && TARGET_IEEE16_PASS_BY_REFERENCE)
-    return true;
-
   if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD
       && FLOAT128_IEEE_P (TYPE_MODE (arg.type)))
     {
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index cd244047ce5e..21f5d13ec715 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -24060,6 +24060,8 @@ rs6000_function_value (const_tree valtype,
   if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT)
     /* _Decimal128 must use an even/odd register pair.  */
     regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
+  else if (mode == HFmode && TARGET_IEEE16_GPR_ARGS)
+    regno = GP_ARG_RETURN;
   else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT
           && !FLOAT128_VECTOR_P (mode))
     regno = FP_ARG_RETURN;
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index a2f74245c42d..093d2156da7d 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -8155,11 +8155,11 @@
     operands[1] = force_reg (HFmode, operands[1]);
 })
 
-;; On power10, we can load up HFmode constants with xxspltiw.
+;; On power10, we can load up HFmode constants with xxspltiw or pli.
 (define_insn "*movhf_xxspltiw"
-  [(set (match_operand:HF 0 "vsx_register_operand" "=wa")
-       (match_operand:HF 1 "ieee16_xxspltiw_constant" "eP"))]
-  "TARGET_IEEE16 && TARGET_POWER10"
+  [(set (match_operand:HF 0 "gpc_reg_operand" "=wa,r")
+       (match_operand:HF 1 "ieee16_xxspltiw_constant" "eP,eP"))]
+  "TARGET_IEEE16 && TARGET_POWER10 && TARGET_PREFIXED"
 {
   rtx op1 = operands[1];
   const REAL_VALUE_TYPE *rtype = CONST_DOUBLE_REAL_VALUE (op1);
@@ -8167,9 +8167,11 @@
 
   real_to_target (real_words, rtype, HFmode);
   operands[2] = GEN_INT (real_words[0]);
-  return "xxspltiw %x0,%2";
+  return (vsx_register_operand (operands[0], HFmode)
+         ? "xxspltiw %x0,%2"
+         : "li %0,%2");
 }
-  [(set_attr "type" "vecperm")
+  [(set_attr "type" "vecperm,*")
    (set_attr "prefixed" "yes")])
 
 (define_insn "*movhf_internal"
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index 8c6f08dc5c8f..5f81d3426a2c 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -642,13 +642,9 @@ mieee128-constant
 Target Var(TARGET_IEEE128_CONSTANT) Init(1) Save
 Generate (do not generate) code that uses the LXVKQ instruction.
 
-mieee16-return-in-memory
-Target Undocumented Var(TARGET_IEEE16_RETURN_IN_MEMORY) Init(1) Save
-Return _Float16 values in memory.
-
-mieee16-pass-by-reference
-Target Undocumented Var(TARGET_IEEE16_PASS_BY_REFERENCE) Init(1) Save
-Pass _Float16 by reference.
+mieee16-gpr-args
+Target Undocumented Var(TARGET_IEEE16_GPR_ARGS) Init(1) Save
+Pass _Float16 in GPR registers.
 
 ; Documented parameters

Reply via email to