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