https://gcc.gnu.org/g:3eeb4d88a51113e7099de67a53d0b7dd55e13c1c

commit 3eeb4d88a51113e7099de67a53d0b7dd55e13c1c
Author: Michael Meissner <meiss...@linux.ibm.com>
Date:   Wed Aug 13 18:54:28 2025 -0400

    Pass _Float16 arguments and return values in memory
    
    2025-08-13  Michael Meissner  <meiss...@linux.ibm.com>
    
    gcc/
    
            PR target/121525
            * config/rs6000/rs6000-call.cc (rs6000_return_in_memory): Return
            _Float16 values in memory unless -mno-ieee16-return-in-memory.
            (rs6000_pass_by_reference): Pass _Float16 values by reference unless
            -mno-ieee16-pass-by-reference.
            * config/rs6000/rs6000.md (movhf): Make sure memory <- memory moves 
are
            not generated.
            * config/rs6000/rs6000.opt (-mieee16-return-in-memory): New debug
            option.
            (-mieee16-pass-by-reference): Likewise.

Diff:
---
 gcc/config/rs6000/rs6000-call.cc | 10 ++++++++++
 gcc/config/rs6000/rs6000.md      |  6 +++++-
 gcc/config/rs6000/rs6000.opt     |  8 ++++++++
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/rs6000-call.cc b/gcc/config/rs6000/rs6000-call.cc
index 8fe5652442e3..d639519a4368 100644
--- a/gcc/config/rs6000/rs6000-call.cc
+++ b/gcc/config/rs6000/rs6000-call.cc
@@ -432,6 +432,11 @@ 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
@@ -1985,6 +1990,11 @@ 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.md b/gcc/config/rs6000/rs6000.md
index b4af2eb4b9c0..a2f74245c42d 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -8149,7 +8149,11 @@
 (define_expand "movhf"
   [(set (match_operand:HF 0 "nonimmediate_operand")
        (match_operand:HF 1 "any_operand"))]
-  "TARGET_IEEE16")
+  "TARGET_IEEE16"
+{
+  if (MEM_P (operands[0]) && !REG_P (operands[1]))
+    operands[1] = force_reg (HFmode, operands[1]);
+})
 
 ;; On power10, we can load up HFmode constants with xxspltiw.
 (define_insn "*movhf_xxspltiw"
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index 39ae7791c60a..8c6f08dc5c8f 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -642,6 +642,14 @@ 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.
+
 ; Documented parameters
 
 -param=rs6000-vect-unroll-limit=

Reply via email to