https://gcc.gnu.org/g:69705411b1cae2c6e96877b1a60fd90601087905
commit 69705411b1cae2c6e96877b1a60fd90601087905 Author: Michael Meissner <[email protected]> Date: Thu Sep 3 22:26:02 2026 -0400 Don't return HFmode/BFmode as SFmode. 2026-09-03 Michael Meissner <[email protected]> gcc/ * config/rs6000/rs6000-call.cc (rs6000_promote_function_mode): Only convert HFmode/BFmode to SFmode, but don't change return value at present. (rs6000_promote_function_mode_convert): Add unsignedp argument. * config/rs6000/rs6000-internal.h (rs6000_promote_function_mode_convert): Update calling sequence. * config/rs6000/rs6000.cc (rs6000_function_value): Undo last change. * doc/tm.texi: Regenerate. * doc/tm.texi.in (TARGET_PROMOTE_FUNCTION_MODE_CONVERT): Update calling sequence. * expr.cc (expand_expr_real_1): Update call to promote_function_mode_convert. * target.def (PROMOTE_FUNCTION_MODE_CONVERT): Update calling sequence. * targhooks.cc (default_promote_function_mode_convert): Likewise. * targhooks.h (default_promote_function_mode_convert): Likewise. Diff: --- gcc/config/rs6000/rs6000-call.cc | 13 ++++++------- gcc/config/rs6000/rs6000-internal.h | 2 +- gcc/config/rs6000/rs6000.cc | 3 --- gcc/doc/tm.texi | 5 +++-- gcc/expr.cc | 16 +++++++++++----- gcc/target.def | 6 ++++-- gcc/targhooks.cc | 7 ++++--- gcc/targhooks.h | 2 +- 8 files changed, 30 insertions(+), 24 deletions(-) diff --git a/gcc/config/rs6000/rs6000-call.cc b/gcc/config/rs6000/rs6000-call.cc index 2c7d864f495b..9460d4fb49ac 100644 --- a/gcc/config/rs6000/rs6000-call.cc +++ b/gcc/config/rs6000/rs6000-call.cc @@ -721,9 +721,9 @@ machine_mode rs6000_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, machine_mode mode, int *punsignedp ATTRIBUTE_UNUSED, - const_tree, int for_return ATTRIBUTE_UNUSED) + const_tree, int for_return) { - if (FP16_SCALAR_MODE_P (mode)) + if (FP16_SCALAR_MODE_P (mode) && !for_return) return SFmode; if (GET_MODE_CLASS (mode) == MODE_INT @@ -738,12 +738,11 @@ rs6000_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, rtx rs6000_promote_function_mode_convert (machine_mode new_mode, machine_mode old_mode, - rtx decl_rtl) + rtx decl_rtl, + int unsignedp) { - if (new_mode != old_mode - && (FP16_SCALAR_MODE_P (new_mode) - || FP16_SCALAR_MODE_P (old_mode))) - return convert_to_mode (new_mode, decl_rtl, 0); + if (FP16_SCALAR_MODE_P (new_mode) || FP16_SCALAR_MODE_P (old_mode)) + return convert_to_mode (new_mode, decl_rtl, unsignedp); return NULL_RTX; } diff --git a/gcc/config/rs6000/rs6000-internal.h b/gcc/config/rs6000/rs6000-internal.h index 7e5b40b73db6..dc8bde7cebb9 100644 --- a/gcc/config/rs6000/rs6000-internal.h +++ b/gcc/config/rs6000/rs6000-internal.h @@ -151,7 +151,7 @@ extern machine_mode rs6000_promote_function_mode (const_tree type ATTRIBUTE_UNUS const_tree, int); extern rtx rs6000_promote_function_mode_convert (machine_mode new_mode, machine_mode old_mode, - rtx decl_rtl); + rtx decl_rtl, int unsignedp); extern bool rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED); extern bool rs6000_return_in_msb (const_tree valtype); diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 9ee451d8912e..7f2b8b71d159 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -24426,9 +24426,6 @@ rs6000_function_value (const_tree valtype, else regno = GP_ARG_RETURN; - if (FP16_SCALAR_MODE_P (mode)) - mode = SFmode; - return gen_rtx_REG (mode, regno); } diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 68721b73d2ce..fd875ed24a5c 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -1110,11 +1110,12 @@ also define the hook to @code{default_promote_function_mode_always_promote} if you would like to apply the same rules given by @code{PROMOTE_MODE}. @end deftypefn -@deftypefn {Target Hook} rtx TARGET_PROMOTE_FUNCTION_MODE_CONVERT (machine_mode @var{new_mode}, machine_mode @var{old_mode}, rtx @var{decl_rtl}) -If @code{PROMOTE_FUNCTION_MODE} returns mode (@code{@var{NEW_MODE}}) which +@deftypefn {Target Hook} rtx TARGET_PROMOTE_FUNCTION_MODE_CONVERT (machine_mode @var{new_mode}, machine_mode @var{old_mode}, rtx @var{decl_rtl}, int @var{unsignedp}) +If @code{PROMOTE_FUNCTION_MODE} returns a mode (@code{@var{NEW_MODE}}) which is a different mode for the function argument or return value (@code{@var{OLD_MODE}}) for @var{DECL_RTL}, either return @code{NULL_RTX} to use @code{SUBREG} to pass the value untranslated, or return a conversion rtl. +The argument @var{UNSIGNEDP} is non-0 if the type is unsigned. The default is to not do a conversion. @end deftypefn diff --git a/gcc/expr.cc b/gcc/expr.cc index ab0d6af870de..4a38c4a97c36 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -11878,11 +11878,17 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, gcc_assert (GET_MODE (decl_rtl) == pmode); /* Convert the value if the target wants it converted. */ - rtx cvt = targetm.calls.promote_function_mode_convert (pmode, mode, - decl_rtl); - - if (cvt) - return EXTEND_BITINT (cvt); + if (pmode != mode) + { + rtx cvt + = targetm.calls.promote_function_mode_convert (pmode, + mode, + decl_rtl, + unsignedp); + + if (cvt) + return EXTEND_BITINT (cvt); + } /* Some ABIs require scalar floating point modes to be passed in a wider scalar integer mode. We need to explicitly diff --git a/gcc/target.def b/gcc/target.def index 884862096154..54158aa51c7e 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -4932,13 +4932,15 @@ if you would like to apply the same rules given by @code{PROMOTE_MODE}.", DEFHOOK (promote_function_mode_convert, - "If @code{PROMOTE_FUNCTION_MODE} returns mode (@code{@var{NEW_MODE}}) which\n\ + "If @code{PROMOTE_FUNCTION_MODE} returns a mode (@code{@var{NEW_MODE}}) which\n\ is a different mode for the function argument or return value\n\ (@code{@var{OLD_MODE}}) for @var{DECL_RTL}, either return @code{NULL_RTX} to\n\ use @code{SUBREG} to pass the value untranslated, or return a conversion rtl.\n\ +The argument @var{UNSIGNEDP} is non-0 if the type is unsigned.\n\ \n\ The default is to not do a conversion.", - rtx, (machine_mode new_mode, machine_mode old_mode, rtx decl_rtl), + rtx, (machine_mode new_mode, machine_mode old_mode, rtx decl_rtl, + int unsignedp), default_promote_function_mode_convert) DEFHOOK diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc index 9ec801e79df9..068c97bfdf46 100644 --- a/gcc/targhooks.cc +++ b/gcc/targhooks.cc @@ -153,9 +153,10 @@ default_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, } rtx -default_promot_function_mode_convert (machine_mode new_mode ATTRIBUTE_UNUSED, - machine_mode old_mode ATTRIBUTE_UNUSED, - rtx decl_rtx ATTRIBUTE_UNUSED) +default_promote_function_mode_convert (machine_mode new_mode ATTRIBUTE_UNUSED, + machine_mode old_mode ATTRIBUTE_UNUSED, + rtx decl_rtx ATTRIBUTE_UNUSED, + int unsignedp ATTRIBUTE_UNUSED) { return NULL_RTX; } diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 204f7f7e0be8..70feec79ceba 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -32,7 +32,7 @@ extern int default_unspec_may_trap_p (const_rtx, unsigned); extern machine_mode default_promote_function_mode (const_tree, machine_mode, int *, const_tree, int); extern rtx default_promote_function_mode_convert (machine_mode, machine_mode, - rtx); + rtx, int); extern machine_mode default_promote_function_mode_always_promote (const_tree, machine_mode, int *, const_tree, int); extern machine_mode default_promote_function_mode_sign_extend
