public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 1/4] rs6000: Make all 128 bit scalar FP modes have 128 bit precision [PR112993]
@ 2024-05-08  5:21 Kewen.Lin
  2024-05-08  5:27 ` [PATCH 2/4] fortran: Teach get_real_kind_from_node for Power 128 fp modes [PR112993] Kewen.Lin
                   ` (3 more replies)
  0 siblings, 4 replies; 19+ messages in thread
From: Kewen.Lin @ 2024-05-08  5:21 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Richard Biener, Richard Sandiford,
	Segher Boessenkool, Peter Bergner, Michael Meissner,
	David Edelsohn

Hi,

On rs6000, there are three 128 bit scalar floating point
modes TFmode, IFmode and KFmode.  With some historical
reasons, we defines them with different mode precisions,
that is KFmode 126, TFmode 127 and IFmode 128.  But in
fact all of them should have the same mode precision 128,
this special setting has caused some issues like some
unexpected failures mentioned in [1] and also made us have
to introduce some workarounds, such as: the workaround in
build_common_tree_nodes for KFmode 126, the workaround in
range_compatible_p for same mode but different precision
issue.

This patch is to make these three 128 bit scalar floating
point modes TFmode, IFmode and KFmode have 128 bit mode
precision, and keep the order same as previous in order
to make machine independent parts of the compiler not try
to widen IFmode to TFmode.  To make build_common_tree_nodes
be able to find the correct mode for long double type node,
it introduces one hook mode_for_longdouble to offer target
a way to specify the mode used for long double type node.
Previously I tried to put the order as TF/KF/IF then long
double type node can pick up the TF as expected, but we
need to teach some functions not to try the conversions
from IF(TF) to KF, one more important thing is that we
would further remove TF and leave only two modes for 128
bit floating point modes, without such hook the first 128
bit mode will be chosen for long double type node but
whichever we replace first would be possible not the
expected one as it actually depends on the selected long
double format.

In function convert_mode_scalar, it adopts sext_optab for
same precision modes conversion if !DECIMAL_FLOAT_MODE_P,
so we only need to support sext_optab for any possible
conversion.  Thus this patch removes some useless trunc
optab supports, supplements one new sext_optab which calls
the common handler rs6000_expand_float128_convert, unnames
two define_insn_and_split to avoid conflicts and make them
more clear.  Considering the current implementation that
there is no chance to have KF <-> IF conversion (since
either of them would be TF already), it adds two dummy
define_expands to assert this.

Bootstrapped and regress-tested (with patch 2/4) on:
  - powerpc64-linux-gnu P8/P9 (with ibm128 by default)
  - powerpc64le-linux-gnu P9/P10 (with ibm128 by default)
  - powerpc64le-linux-gnu P9 (with ieee128 by default)

Is it OK for trunk (especially the generic code change)?

[1] https://inbox.sourceware.org/gcc-patches/
    718677e7-614d-7977-312d-05a75e1fd5b4@linux.ibm.com/

BR,
Kewen
-----
	PR target/112993

gcc/ChangeLog:

	* config/rs6000/rs6000-modes.def (IFmode, KFmode, TFmode): Define
	with FLOAT_MODE instead of FRACTIONAL_FLOAT_MODE, don't use special
	precisions any more.
	(rs6000-modes.h): Remove include.
	* config/rs6000/rs6000-modes.h: Remove.
	* config/rs6000/rs6000.h (rs6000-modes.h): Remove include.
	* config/rs6000/t-rs6000: Remove rs6000-modes.h include.
	* config/rs6000/rs6000.cc (rs6000_option_override_internal): Replace
	all uses of FLOAT_PRECISION_TFmode with 128.
	(TARGET_C_MODE_FOR_LONGDOUBLE): New macro.
	(rs6000_c_mode_for_longdouble): New hook implementation.
	* config/rs6000/rs6000.md (define_expand trunciftf2): Remove.
	(define_expand truncifkf2): Remove.
	(define_expand trunckftf2): Remove.
	(define_expand trunctfif2): Remove.
	(define_expand expandtfkf2, expandtfif2): Merge to ...
        (define_expand expandtf<IFKF>2): ... this, new.
	(define_expand expandiftf2): Merge to ...
        (define_expand expand<IFKF>tf2): ... this, new.
	(define_expand expandiftf2): Update with assert.
	(define_expand expandkfif2): New.
	(define_insn_and_split extendkftf2): Rename to  ...
	(define_insn_and_split *extendkftf2): ... this.
	(define_insn_and_split trunctfkf2): Rename to ...
	(define_insn_and_split *extendtfkf2): ... this.
	* expr.cc (convert_mode_scalar): Allow same precision conversion
	between scalar floating point modes if whose underlying format is
	ibm_extended_format or ieee_quad_format, and refactor assertion
	with new lambda function acceptable_same_precision_modes.
	* doc/tm.texi: Regenerate.
	* doc/tm.texi.in (TARGET_C_MODE_FOR_LONGDOUBLE): New hook.
	* target.def (mode_for_longdouble): Likewise.
	* targhooks.cc (default_mode_for_longdouble): New hook default
	implementation.
	* targhooks.h (default_mode_for_longdouble): New hook declaration.
	* tree.cc (build_common_tree_nodes): Call newly added hook
	targetm.c.mode_for_longdouble.
---
 gcc/config/rs6000/rs6000-modes.def | 31 +++++--------
 gcc/config/rs6000/rs6000-modes.h   | 36 ---------------
 gcc/config/rs6000/rs6000.cc        | 18 +++++---
 gcc/config/rs6000/rs6000.h         |  5 ---
 gcc/config/rs6000/rs6000.md        | 72 ++++++++----------------------
 gcc/config/rs6000/t-rs6000         |  1 -
 gcc/doc/tm.texi                    |  6 +++
 gcc/doc/tm.texi.in                 |  2 +
 gcc/expr.cc                        | 27 ++++++++---
 gcc/target.def                     |  7 +++
 gcc/targhooks.cc                   |  9 ++++
 gcc/targhooks.h                    |  1 +
 gcc/tree.cc                        |  1 +
 13 files changed, 90 insertions(+), 126 deletions(-)
 delete mode 100644 gcc/config/rs6000/rs6000-modes.h

diff --git a/gcc/config/rs6000/rs6000-modes.def b/gcc/config/rs6000/rs6000-modes.def
index 094b246c834..b69593c40a6 100644
--- a/gcc/config/rs6000/rs6000-modes.def
+++ b/gcc/config/rs6000/rs6000-modes.def
@@ -18,12 +18,11 @@
    along with GCC; see the file COPYING3.  If not see
    <http://www.gnu.org/licenses/>.  */

-/* We order the 3 128-bit floating point types so that IFmode (IBM 128-bit
-   floating point) is the 128-bit floating point type with the highest
-   precision (128 bits).  This so that machine independent parts of the
-   compiler do not try to widen IFmode to TFmode on ISA 3.0 (power9) that has
-   hardware support for IEEE 128-bit.  We set TFmode (long double mode) in
-   between, and KFmode (explicit __float128) below it.
+/* We order the 3 128-bit floating point type modes here as KFmode, TFmode and
+   IFmode, it is the same as the previous order, to make machine independent
+   parts of the compiler do not try to widen IFmode to TFmode on ISA 3.0
+   (power9) that has hardware support for IEEE 128-bit.  We set TFmode (long
+   double mode) in between, and KFmode (explicit __float128) below it.

    Previously, IFmode and KFmode were defined to be fractional modes and TFmode
    was the standard mode.  Since IFmode does not define the normal arithmetic
@@ -33,24 +32,18 @@
    128-bit is not strictly a super-set of IBM extended double and the
    conversion to/from IEEE 128-bit was a function call.

-   We now make IFmode the highest fractional mode, which means its values are
-   not considered for widening.  Since we don't define insns for IFmode, the
-   IEEE 128-bit modes would not widen to IFmode.  */
-
-#ifndef RS6000_MODES_H
-#include "config/rs6000/rs6000-modes.h"
-#endif
-
-/* IBM 128-bit floating point.  */
-FRACTIONAL_FLOAT_MODE (IF, FLOAT_PRECISION_IFmode, 16, ibm_extended_format);
+   We now place IFmode last, which means its values are not considered for
+   widening.  Since we don't define insns for IFmode, the IEEE 128-bit modes
+   would not widen to IFmode.  */

 /* Explicit IEEE 128-bit floating point.  */
-FRACTIONAL_FLOAT_MODE (KF, FLOAT_PRECISION_KFmode, 16, ieee_quad_format);
-
+FLOAT_MODE (KF, 16, ieee_quad_format);
 /* 128-bit floating point, either IBM 128-bit or IEEE 128-bit.  This is
    adjusted in rs6000_option_override_internal to be the appropriate floating
    point type.  */
-FRACTIONAL_FLOAT_MODE (TF, FLOAT_PRECISION_TFmode, 16, ieee_quad_format);
+FLOAT_MODE (TF, 16, ieee_quad_format);
+/* IBM 128-bit floating point.  */
+FLOAT_MODE (IF, 16, ibm_extended_format);

 /* Add any extra modes needed to represent the condition code.

diff --git a/gcc/config/rs6000/rs6000-modes.h b/gcc/config/rs6000/rs6000-modes.h
deleted file mode 100644
index cf95330c265..00000000000
--- a/gcc/config/rs6000/rs6000-modes.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Definitions 128-bit floating point precisions used by PowerPC.
-   Copyright (C) 2018-2024 Free Software Foundation, Inc.
-   Contributed by Michael Meissner (meissner@linux.ibm.com)
-
-   This file is part of GCC.
-
-   GCC is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published
-   by the Free Software Foundation; either version 3, or (at your
-   option) any later version.
-
-   GCC is distributed in the hope that it will be useful, but WITHOUT
-   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
-   License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with GCC; see the file COPYING3.  If not see
-   <http://www.gnu.org/licenses/>.  */
-
-/* We order the 3 128-bit floating point types so that IFmode (IBM 128-bit
-   floating point) is the 128-bit floating point type with the highest
-   precision (128 bits).  This so that machine independent parts of the
-   compiler do not try to widen IFmode to TFmode on ISA 3.0 (power9) that has
-   hardware support for IEEE 128-bit.  We set TFmode (long double mode) in
-   between, and KFmode (explicit __float128) below it.
-
-   We won't encounter conversion from IEEE 128-bit to IBM 128-bit because we
-   don't have insns to support the IBM 128-bit aritmetic operations.  */
-
-#ifndef RS6000_MODES_H
-#define RS6000_MODES_H		1
-#define FLOAT_PRECISION_IFmode	128
-#define FLOAT_PRECISION_TFmode	127
-#define FLOAT_PRECISION_KFmode	126
-#endif	/* RS6000_MODES_H */
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 6ba9df4f02e..518edf5d42a 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -1707,6 +1707,9 @@ static const scoped_attribute_specs *const rs6000_attribute_table[] =
 #undef TARGET_C_MODE_FOR_SUFFIX
 #define TARGET_C_MODE_FOR_SUFFIX rs6000_c_mode_for_suffix

+#undef TARGET_C_MODE_FOR_LONGDOUBLE
+#define TARGET_C_MODE_FOR_LONGDOUBLE rs6000_c_mode_for_longdouble
+
 #undef TARGET_INVALID_BINARY_OP
 #define TARGET_INVALID_BINARY_OP rs6000_invalid_binary_op

@@ -4093,7 +4096,7 @@ rs6000_option_override_internal (bool global_init_p)
      128 into the precision used for TFmode.  */
   int default_long_double_size = (RS6000_DEFAULT_LONG_DOUBLE_SIZE == 64
 				  ? 64
-				  : FLOAT_PRECISION_TFmode);
+				  : 128);

   /* Set long double size before the IEEE 128-bit tests.  */
   if (!OPTION_SET_P (rs6000_long_double_type_size))
@@ -4105,10 +4108,6 @@ rs6000_option_override_internal (bool global_init_p)
       else
 	rs6000_long_double_type_size = default_long_double_size;
     }
-  else if (rs6000_long_double_type_size == FLOAT_PRECISION_TFmode)
-    ; /* The option value can be seen when cl_target_option_restore is called.  */
-  else if (rs6000_long_double_type_size == 128)
-    rs6000_long_double_type_size = FLOAT_PRECISION_TFmode;

   /* Set -mabi=ieeelongdouble on some old targets.  In the future, power server
      systems will also set long double to be IEEE 128-bit.  AIX and Darwin
@@ -24370,6 +24369,15 @@ rs6000_c_mode_for_suffix (char suffix)
   return VOIDmode;
 }

+/* Target hook for c_mode_for_longdouble.  */
+static machine_mode
+rs6000_c_mode_for_longdouble ()
+{
+  if (TARGET_LONG_DOUBLE_128)
+    return TFmode;
+  return VOIDmode;
+}
+
 /* Target hook for invalid_arg_for_unprototyped_fn. */
 static const char *
 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 68bc45d65ba..ec7e26e165c 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -30,11 +30,6 @@
 #include "config/rs6000/rs6000-opts.h"
 #endif

-/* 128-bit floating point precision values.  */
-#ifndef RS6000_MODES_H
-#include "config/rs6000/rs6000-modes.h"
-#endif
-
 /* Definitions for the object file format.  These are set at
    compile-time.  */

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index bc8bc6ab060..91b323f15f8 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -9337,79 +9337,43 @@ (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
   "xxlor %x0,%x1,%x2"
   [(set_attr "type" "veclogical")])

-;; Float128 conversion functions.  These expand to library function calls.
-;; We use expand to convert from IBM double double to IEEE 128-bit
-;; and trunc for the opposite.
-(define_expand "extendiftf2"
+;; Float128 conversion functions.
+;; If the conversion happens between IBM double double and
+;; IEEE 128-bit, it expands to library function calls.
+;; Generic code adopts sext_optab for same precision scalar
+;; float modes conversion, so we just need to define extend.
+(define_expand "extend<mode>tf2"
   [(set (match_operand:TF 0 "gpc_reg_operand")
-	(float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
+	(float_extend:TF (match_operand:IFKF 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
 })

-(define_expand "extendifkf2"
-  [(set (match_operand:KF 0 "gpc_reg_operand")
-	(float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
-  "TARGET_FLOAT128_TYPE"
-{
-  rs6000_expand_float128_convert (operands[0], operands[1], false);
-  DONE;
-})
-
-(define_expand "extendtfkf2"
-  [(set (match_operand:KF 0 "gpc_reg_operand")
-	(float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
+(define_expand "extendtf<mode>2"
+  [(set (match_operand:IFKF 0 "gpc_reg_operand")
+	(float_extend:IFKF (match_operand:TF 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
 })

-(define_expand "extendtfif2"
-  [(set (match_operand:IF 0 "gpc_reg_operand")
-	(float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
-  "TARGET_FLOAT128_TYPE"
-{
-  rs6000_expand_float128_convert (operands[0], operands[1], false);
-  DONE;
-})
-
-(define_expand "trunciftf2"
-  [(set (match_operand:TF 0 "gpc_reg_operand")
-	(float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
-  "TARGET_FLOAT128_TYPE"
-{
-  rs6000_expand_float128_convert (operands[0], operands[1], false);
-  DONE;
-})
-
-(define_expand "truncifkf2"
+(define_expand "extendifkf2"
   [(set (match_operand:KF 0 "gpc_reg_operand")
-	(float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
-  "TARGET_FLOAT128_TYPE"
-{
-  rs6000_expand_float128_convert (operands[0], operands[1], false);
-  DONE;
-})
-
-(define_expand "trunckftf2"
-  [(set (match_operand:TF 0 "gpc_reg_operand")
-	(float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
+	(float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
-  rs6000_expand_float128_convert (operands[0], operands[1], false);
-  DONE;
+  gcc_assert (false);
 })

-(define_expand "trunctfif2"
+(define_expand "extendkfif2"
   [(set (match_operand:IF 0 "gpc_reg_operand")
-	(float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
+	(float_extend:IF (match_operand:KF 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
-  rs6000_expand_float128_convert (operands[0], operands[1], false);
-  DONE;
+  gcc_assert (false);
 })

 (define_insn_and_split "*extend<mode>tf2_internal"
@@ -15161,7 +15125,7 @@ (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"

 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
 ;; point is a simple copy.
-(define_insn_and_split "extendkftf2"
+(define_insn_and_split "*extendkftf2"
   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
 	(float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
@@ -15177,7 +15141,7 @@ (define_insn_and_split "extendkftf2"
   [(set_attr "type" "*,veclogical")
    (set_attr "length" "0,4")])

-(define_insn_and_split "trunctfkf2"
+(define_insn_and_split "*extendtfkf2"
   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
 	(float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000
index b3ce09d523b..155788de40a 100644
--- a/gcc/config/rs6000/t-rs6000
+++ b/gcc/config/rs6000/t-rs6000
@@ -19,7 +19,6 @@
 # <http://www.gnu.org/licenses/>.

 TM_H += $(srcdir)/config/rs6000/rs6000-cpus.def
-TM_H += $(srcdir)/config/rs6000/rs6000-modes.h
 PASSES_EXTRA += $(srcdir)/config/rs6000/rs6000-passes.def
 EXTRA_GTYPE_DEPS += rs6000-builtins.h

diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index c8b8b126b24..7c8b7fcabba 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -1044,6 +1044,12 @@ are zero or sign extended depending on if it is
 @code{GET_MODE_ALIGNMENT (info->limb_mode)}.
 @end deftypefn

+@deftypefn {Target Hook} machine_mode TARGET_C_MODE_FOR_LONGDOUBLE ()
+Return machine mode for long double type, use it if it is not
+ @code{VOIDmode}, otherwise find an appropriate machine mode with
+ mode precision @code{LONG_DOUBLE_TYPE_SIZE}.
+@end deftypefn
+
 @deftypefn {Target Hook} machine_mode TARGET_PROMOTE_FUNCTION_MODE (const_tree @var{type}, machine_mode @var{mode}, int *@var{punsignedp}, const_tree @var{funtype}, int @var{for_return})
 Like @code{PROMOTE_MODE}, but it is applied to outgoing function arguments or
 function return values.  The target hook should return the new mode
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 658e1e63371..a26f4a11ac6 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -947,6 +947,8 @@ applied.

 @hook TARGET_C_BITINT_TYPE_INFO

+@hook TARGET_C_MODE_FOR_LONGDOUBLE
+
 @hook TARGET_PROMOTE_FUNCTION_MODE

 @defmac PARM_BOUNDARY
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 8d34d024c9c..f5230b9cc44 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -339,6 +339,26 @@ convert_mode_scalar (rtx to, rtx from, int unsignedp)
   enum rtx_code equiv_code = (unsignedp < 0 ? UNKNOWN
 			      : (unsignedp ? ZERO_EXTEND : SIGN_EXTEND));

+  auto acceptable_same_precision_modes
+    = [] (scalar_mode from_mode, scalar_mode to_mode) {
+	if (DECIMAL_FLOAT_MODE_P (from_mode) != DECIMAL_FLOAT_MODE_P (to_mode))
+	  return true;
+	/* arm_bfloat_half_format <-> ieee_half_format */
+	if ((REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
+	     && REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
+	    || (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
+		&& REAL_MODE_FORMAT (from_mode) == &ieee_half_format))
+	  return true;
+	/* ibm_extended_format <-> ieee_quad_format */
+	if ((REAL_MODE_FORMAT (from_mode) == &ibm_extended_format
+	     && REAL_MODE_FORMAT (to_mode) == &ieee_quad_format)
+	    || (REAL_MODE_FORMAT (from_mode) == &ieee_quad_format
+		&& REAL_MODE_FORMAT (to_mode) == &ibm_extended_format))
+	  return true;
+
+	return false;
+      };
+
   if (to_real)
     {
       rtx value;
@@ -347,12 +367,7 @@ convert_mode_scalar (rtx to, rtx from, int unsignedp)

       gcc_assert ((GET_MODE_PRECISION (from_mode)
 		   != GET_MODE_PRECISION (to_mode))
-		  || (DECIMAL_FLOAT_MODE_P (from_mode)
-		      != DECIMAL_FLOAT_MODE_P (to_mode))
-		  || (REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
-		      && REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
-		  || (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
-		      && REAL_MODE_FORMAT (from_mode) == &ieee_half_format));
+		  || acceptable_same_precision_modes (from_mode, to_mode));

       if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode))
 	/* Conversion between decimal float and binary float, same size.  */
diff --git a/gcc/target.def b/gcc/target.def
index fdad7bbc93e..2b821612e80 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -6370,6 +6370,13 @@ are zero or sign extended depending on if it is\n\
  bool, (int n, struct bitint_info *info),
  default_bitint_type_info)

+DEFHOOK
+(mode_for_longdouble,
+"Return machine mode for long double type, use it if it is not\n\
+ @code{VOIDmode}, otherwise find an appropriate machine mode with\n\
+ mode precision @code{LONG_DOUBLE_TYPE_SIZE}.",
+ machine_mode, (), default_mode_for_longdouble)
+
 HOOK_VECTOR_END (c)

 /* Functions specific to the C++ frontend.  */
diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
index 8c84deea97d..b68025acff4 100644
--- a/gcc/targhooks.cc
+++ b/gcc/targhooks.cc
@@ -298,6 +298,15 @@ default_mode_for_suffix (char suffix ATTRIBUTE_UNUSED)
   return VOIDmode;
 }

+/* Return machine mode for long double node type.
+   VOIDmode means caller should find an appropriate one with
+   mode precision LONG_DOUBLE_TYPE_SIZE.  */
+machine_mode
+default_mode_for_longdouble ()
+{
+  return VOIDmode;
+}
+
 /* The generic C++ ABI specifies this is a 64-bit value.  */
 tree
 default_cxx_guard_type (void)
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index ca289f30eda..7b720c1064d 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -62,6 +62,7 @@ extern tree default_external_stack_protect_fail (void);
 extern tree default_hidden_stack_protect_fail (void);

 extern machine_mode default_mode_for_suffix (char);
+extern machine_mode default_mode_for_longdouble ();

 extern tree default_cxx_guard_type (void);
 extern tree default_cxx_get_cookie_size (tree);
diff --git a/gcc/tree.cc b/gcc/tree.cc
index f730981ec8b..cc7721cab26 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -9565,6 +9565,7 @@ build_common_tree_nodes (bool signed_char)

   long_double_type_node = make_node (REAL_TYPE);
   TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE;
+  SET_TYPE_MODE (long_double_type_node, targetm.c.mode_for_longdouble ());
   layout_type (long_double_type_node);

   for (i = 0; i < NUM_FLOATN_NX_TYPES; i++)
--
2.39.1

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 2/4] fortran: Teach get_real_kind_from_node for Power 128 fp modes [PR112993]
  2024-05-08  5:21 [PATCH 1/4] rs6000: Make all 128 bit scalar FP modes have 128 bit precision [PR112993] Kewen.Lin
@ 2024-05-08  5:27 ` Kewen.Lin
  2024-05-08  7:40   ` Mikael Morin
  2024-05-08 22:01   ` [PATCH 2/4] fortran: Teach get_real_kind_from_node for Power 128 fp modes [PR112993]g Steve Kargl
  2024-05-08  5:32 ` [PATCH 3/4] ranger: Revert the workaround introduced in PR112788 [PR112993] Kewen.Lin
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 19+ messages in thread
From: Kewen.Lin @ 2024-05-08  5:27 UTC (permalink / raw)
  To: GCC Patches
  Cc: fortran, Jakub Jelinek, Segher Boessenkool, Peter Bergner,
	David Edelsohn

Hi,

Previously effective target fortran_real_c_float128 never
passes on Power regardless of the default 128 long double
is ibmlongdouble or ieeelongdouble.  It's due to that TF
mode is always used for kind 16 real, which has precision
127, while the node float128_type_node for c_float128 has
128 type precision, get_real_kind_from_node can't find a
matching as it only checks gfc_real_kinds[i].mode_precision
and type precision.

With changing TFmode/IFmode/KFmode to have the same mode
precision 128, now fortran_real_c_float12 can pass with
ieeelongdouble enabled by default and test cases guarded
with it get tested accordingly.  But with ibmlongdouble
enabled by default, since TFmode has precision 128 which
is the same as type precision 128 of float128_type_node,
get_real_kind_from_node considers kind for TFmode matches
float128_type_node, but it's wrong as at this time point
TFmode is with ibm extended format.  So this patch is to
teach get_real_kind_from_node to check one more field which
can be differentiable from the underlying real format, it
can avoid the unexpected matching when there more than one
modes have the same precision.

Bootstrapped and regress-tested on:
  - powerpc64-linux-gnu P8/P9 (with ibm128 by default)
  - powerpc64le-linux-gnu P9/P10 (with ibm128 by default)
  - powerpc64le-linux-gnu P9 (with ieee128 by default)

BR,
Kewen
-----
	PR target/112993

gcc/fortran/ChangeLog:

	* trans-types.cc (get_real_kind_from_node): Consider the case where
	more than one modes have the same precision.
---
 gcc/fortran/trans-types.cc | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index 676014e9b98..dd94ef77741 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -183,7 +183,21 @@ get_real_kind_from_node (tree type)

   for (i = 0; gfc_real_kinds[i].kind != 0; i++)
     if (gfc_real_kinds[i].mode_precision == TYPE_PRECISION (type))
-      return gfc_real_kinds[i].kind;
+      {
+	/* On Power, we have three 128-bit scalar floating-point modes
+	   and all of their types have 128 bit type precision, so we
+	   should check underlying real format details further.  */
+#if defined(HAVE_TFmode) && defined(HAVE_IFmode) && defined(HAVE_KFmode)
+	if (gfc_real_kinds[i].kind == 16)
+	  {
+	    machine_mode mode = TYPE_MODE (type);
+	    const struct real_format *fmt = REAL_MODE_FORMAT (mode);
+	    if (fmt->p != gfc_real_kinds[i].digits)
+	      continue;
+	  }
+#endif
+	return gfc_real_kinds[i].kind;
+      }

   return -4;
 }
--
2.39.1

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 3/4] ranger: Revert the workaround introduced in PR112788 [PR112993]
  2024-05-08  5:21 [PATCH 1/4] rs6000: Make all 128 bit scalar FP modes have 128 bit precision [PR112993] Kewen.Lin
  2024-05-08  5:27 ` [PATCH 2/4] fortran: Teach get_real_kind_from_node for Power 128 fp modes [PR112993] Kewen.Lin
@ 2024-05-08  5:32 ` Kewen.Lin
  2024-05-08 14:06   ` Aldy Hernandez
  2024-05-08  5:36 ` [PATCH 4/4] tree: Remove KFmode workaround [PR112993] Kewen.Lin
  2024-05-09 19:12 ` [PATCH 1/4] rs6000: Make all 128 bit scalar FP modes have 128 bit precision [PR112993] Joseph Myers
  3 siblings, 1 reply; 19+ messages in thread
From: Kewen.Lin @ 2024-05-08  5:32 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Segher Boessenkool, Peter Bergner,
	Michael Meissner, David Edelsohn, Andrew MacLeod, hernandez,
	aldy

Hi,

This reverts commit r14-6478-gfda8e2f8292a90 "range:
Workaround different type precision between _Float128 and
long double [PR112788]" as the fixes for PR112993 make
all 128 bits scalar floating point have the same 128 bit
precision, this workaround isn't needed any more.

Bootstrapped and regress-tested on:
  - powerpc64-linux-gnu P8/P9 (with ibm128 by default)
  - powerpc64le-linux-gnu P9/P10 (with ibm128 by default)
  - powerpc64le-linux-gnu P9 (with ieee128 by default)

Is it OK for trunk if {1,2}/4 in this series get landed?

BR,
Kewen
-----

	PR target/112993

gcc/ChangeLog:

	* value-range.h (range_compatible_p): Remove the workaround on
	different type precision between _Float128 and long double.
---
 gcc/value-range.h | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/gcc/value-range.h b/gcc/value-range.h
index 9531df56988..39de7daf3d9 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -1558,13 +1558,7 @@ range_compatible_p (tree type1, tree type2)
   // types_compatible_p requires conversion in both directions to be useless.
   // GIMPLE only requires a cast one way in order to be compatible.
   // Ranges really only need the sign and precision to be the same.
-  return TYPE_SIGN (type1) == TYPE_SIGN (type2)
-	 && (TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
-	     // FIXME: As PR112788 shows, for now on rs6000 _Float128 has
-	     // type precision 128 while long double has type precision 127
-	     // but both have the same mode so their precision is actually
-	     // the same, workaround it temporarily.
-	     || (SCALAR_FLOAT_TYPE_P (type1)
-		 && TYPE_MODE (type1) == TYPE_MODE (type2)));
+  return (TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
+	  && TYPE_SIGN (type1) == TYPE_SIGN (type2));
 }
 #endif // GCC_VALUE_RANGE_H
--
2.39.1

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 4/4] tree: Remove KFmode workaround [PR112993]
  2024-05-08  5:21 [PATCH 1/4] rs6000: Make all 128 bit scalar FP modes have 128 bit precision [PR112993] Kewen.Lin
  2024-05-08  5:27 ` [PATCH 2/4] fortran: Teach get_real_kind_from_node for Power 128 fp modes [PR112993] Kewen.Lin
  2024-05-08  5:32 ` [PATCH 3/4] ranger: Revert the workaround introduced in PR112788 [PR112993] Kewen.Lin
@ 2024-05-08  5:36 ` Kewen.Lin
  2024-05-09 19:12 ` [PATCH 1/4] rs6000: Make all 128 bit scalar FP modes have 128 bit precision [PR112993] Joseph Myers
  3 siblings, 0 replies; 19+ messages in thread
From: Kewen.Lin @ 2024-05-08  5:36 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Segher Boessenkool, Peter Bergner,
	Michael Meissner, David Edelsohn, Joseph S. Myers

Hi,

The fix for PR112993 makes KFmode have 128 bit mode precision,
we don't need this workaround to fix up the type precision any
more, and just go with mode precision.  So this patch is to
remove KFmode workaround.

Bootstrapped and regress-tested on:
  - powerpc64-linux-gnu P8/P9 (with ibm128 by default)
  - powerpc64le-linux-gnu P9/P10 (with ibm128 by default)
  - powerpc64le-linux-gnu P9 (with ieee128 by default)

Is it OK for trunk if {1,2}/4 in this series get landed?

BR,
Kewen
-----

	PR target/112993

gcc/ChangeLog:

	* tree.cc (build_common_tree_nodes): Drop the workaround for rs6000
	KFmode precision adjustment.
---
 gcc/tree.cc | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/gcc/tree.cc b/gcc/tree.cc
index f801712c9dd..f730981ec8b 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -9575,15 +9575,6 @@ build_common_tree_nodes (bool signed_char)
       if (!targetm.floatn_mode (n, extended).exists (&mode))
 	continue;
       int precision = GET_MODE_PRECISION (mode);
-      /* Work around the rs6000 KFmode having precision 113 not
-	 128.  */
-      const struct real_format *fmt = REAL_MODE_FORMAT (mode);
-      gcc_assert (fmt->b == 2 && fmt->emin + fmt->emax == 3);
-      int min_precision = fmt->p + ceil_log2 (fmt->emax - fmt->emin);
-      if (!extended)
-	gcc_assert (min_precision == n);
-      if (precision < min_precision)
-	precision = min_precision;
       FLOATN_NX_TYPE_NODE (i) = make_node (REAL_TYPE);
       TYPE_PRECISION (FLOATN_NX_TYPE_NODE (i)) = precision;
       layout_type (FLOATN_NX_TYPE_NODE (i));
--
2.39.1

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 2/4] fortran: Teach get_real_kind_from_node for Power 128 fp modes [PR112993]
  2024-05-08  5:27 ` [PATCH 2/4] fortran: Teach get_real_kind_from_node for Power 128 fp modes [PR112993] Kewen.Lin
@ 2024-05-08  7:40   ` Mikael Morin
  2024-05-08 22:01   ` [PATCH 2/4] fortran: Teach get_real_kind_from_node for Power 128 fp modes [PR112993]g Steve Kargl
  1 sibling, 0 replies; 19+ messages in thread
From: Mikael Morin @ 2024-05-08  7:40 UTC (permalink / raw)
  To: Kewen.Lin, GCC Patches
  Cc: fortran, Jakub Jelinek, Segher Boessenkool, Peter Bergner,
	David Edelsohn

Hello,

Le 08/05/2024 à 07:27, Kewen.Lin a écrit :
> Hi,
> 
> Previously effective target fortran_real_c_float128 never
> passes on Power regardless of the default 128 long double
> is ibmlongdouble or ieeelongdouble.  It's due to that TF
> mode is always used for kind 16 real, which has precision
> 127, while the node float128_type_node for c_float128 has
> 128 type precision, get_real_kind_from_node can't find a
> matching as it only checks gfc_real_kinds[i].mode_precision
> and type precision.
> 
> With changing TFmode/IFmode/KFmode to have the same mode
> precision 128, now fortran_real_c_float12 can pass with
> ieeelongdouble enabled by default and test cases guarded
> with it get tested accordingly.  But with ibmlongdouble
> enabled by default, since TFmode has precision 128 which
> is the same as type precision 128 of float128_type_node,
> get_real_kind_from_node considers kind for TFmode matches
> float128_type_node, but it's wrong as at this time point
> TFmode is with ibm extended format.  So this patch is to
> teach get_real_kind_from_node to check one more field which
> can be differentiable from the underlying real format, it
> can avoid the unexpected matching when there more than one
> modes have the same precision.
> 
> Bootstrapped and regress-tested on:
>    - powerpc64-linux-gnu P8/P9 (with ibm128 by default)
>    - powerpc64le-linux-gnu P9/P10 (with ibm128 by default)
>    - powerpc64le-linux-gnu P9 (with ieee128 by default)
> 
OK from the fortran point of view.
Thanks.

> BR,
> Kewen


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/4] ranger: Revert the workaround introduced in PR112788 [PR112993]
  2024-05-08  5:32 ` [PATCH 3/4] ranger: Revert the workaround introduced in PR112788 [PR112993] Kewen.Lin
@ 2024-05-08 14:06   ` Aldy Hernandez
  0 siblings, 0 replies; 19+ messages in thread
From: Aldy Hernandez @ 2024-05-08 14:06 UTC (permalink / raw)
  To: Kewen.Lin
  Cc: GCC Patches, Jakub Jelinek, Segher Boessenkool, Peter Bergner,
	Michael Meissner, David Edelsohn, Andrew MacLeod

[-- Attachment #1: Type: text/plain, Size: 2158 bytes --]

I'll defer to the PPC maintainers, but LGTM. The less special casing, the
better.

Aldy

On Wed, May 8, 2024, 07:33 Kewen.Lin <linkw@linux.ibm.com> wrote:

> Hi,
>
> This reverts commit r14-6478-gfda8e2f8292a90 "range:
> Workaround different type precision between _Float128 and
> long double [PR112788]" as the fixes for PR112993 make
> all 128 bits scalar floating point have the same 128 bit
> precision, this workaround isn't needed any more.
>
> Bootstrapped and regress-tested on:
>   - powerpc64-linux-gnu P8/P9 (with ibm128 by default)
>   - powerpc64le-linux-gnu P9/P10 (with ibm128 by default)
>   - powerpc64le-linux-gnu P9 (with ieee128 by default)
>
> Is it OK for trunk if {1,2}/4 in this series get landed?
>
> BR,
> Kewen
> -----
>
>         PR target/112993
>
> gcc/ChangeLog:
>
>         * value-range.h (range_compatible_p): Remove the workaround on
>         different type precision between _Float128 and long double.
> ---
>  gcc/value-range.h | 10 ++--------
>  1 file changed, 2 insertions(+), 8 deletions(-)
>
> diff --git a/gcc/value-range.h b/gcc/value-range.h
> index 9531df56988..39de7daf3d9 100644
> --- a/gcc/value-range.h
> +++ b/gcc/value-range.h
> @@ -1558,13 +1558,7 @@ range_compatible_p (tree type1, tree type2)
>    // types_compatible_p requires conversion in both directions to be
> useless.
>    // GIMPLE only requires a cast one way in order to be compatible.
>    // Ranges really only need the sign and precision to be the same.
> -  return TYPE_SIGN (type1) == TYPE_SIGN (type2)
> -        && (TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
> -            // FIXME: As PR112788 shows, for now on rs6000 _Float128 has
> -            // type precision 128 while long double has type precision 127
> -            // but both have the same mode so their precision is actually
> -            // the same, workaround it temporarily.
> -            || (SCALAR_FLOAT_TYPE_P (type1)
> -                && TYPE_MODE (type1) == TYPE_MODE (type2)));
> +  return (TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
> +         && TYPE_SIGN (type1) == TYPE_SIGN (type2));
>  }
>  #endif // GCC_VALUE_RANGE_H
> --
> 2.39.1
>
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 2/4] fortran: Teach get_real_kind_from_node for Power 128 fp modes [PR112993]g
  2024-05-08  5:27 ` [PATCH 2/4] fortran: Teach get_real_kind_from_node for Power 128 fp modes [PR112993] Kewen.Lin
  2024-05-08  7:40   ` Mikael Morin
@ 2024-05-08 22:01   ` Steve Kargl
  2024-05-09  5:37     ` Kewen.Lin
  1 sibling, 1 reply; 19+ messages in thread
From: Steve Kargl @ 2024-05-08 22:01 UTC (permalink / raw)
  To: Kewen.Lin
  Cc: GCC Patches, fortran, Jakub Jelinek, Segher Boessenkool,
	Peter Bergner, David Edelsohn

On Wed, May 08, 2024 at 01:27:53PM +0800, Kewen.Lin wrote:
> 
> Previously effective target fortran_real_c_float128 never
> passes on Power regardless of the default 128 long double
> is ibmlongdouble or ieeelongdouble.  It's due to that TF
> mode is always used for kind 16 real, which has precision
> 127, while the node float128_type_node for c_float128 has
> 128 type precision, get_real_kind_from_node can't find a
> matching as it only checks gfc_real_kinds[i].mode_precision
> and type precision.
> 
> With changing TFmode/IFmode/KFmode to have the same mode
> precision 128, now fortran_real_c_float12 can pass with
> ieeelongdouble enabled by default and test cases guarded
> with it get tested accordingly.  But with ibmlongdouble
> enabled by default, since TFmode has precision 128 which
> is the same as type precision 128 of float128_type_node,
> get_real_kind_from_node considers kind for TFmode matches
> float128_type_node, but it's wrong as at this time point
> TFmode is with ibm extended format.  So this patch is to
> teach get_real_kind_from_node to check one more field which
> can be differentiable from the underlying real format, it
> can avoid the unexpected matching when there more than one
> modes have the same precision.
> 
> Bootstrapped and regress-tested on:
>   - powerpc64-linux-gnu P8/P9 (with ibm128 by default)
>   - powerpc64le-linux-gnu P9/P10 (with ibm128 by default)
>   - powerpc64le-linux-gnu P9 (with ieee128 by default)
> 
> BR,
> Kewen
> -----
> 	PR target/112993
> 

First, I have no issue with Mikael's OK for committing the
patch. 

That said, Fortran has the concept of model numbers, which
are set in arith.c.  Does this change give the expected 
value for ibm128?  For example, with "REAL(16) X", one
has "DIGITS(X) = 113", which is the precision on the 
of the underlying IEEE754 binary128 type.

-- 
Steve

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 2/4] fortran: Teach get_real_kind_from_node for Power 128 fp modes [PR112993]g
  2024-05-08 22:01   ` [PATCH 2/4] fortran: Teach get_real_kind_from_node for Power 128 fp modes [PR112993]g Steve Kargl
@ 2024-05-09  5:37     ` Kewen.Lin
  2024-05-09 16:47       ` Steve Kargl
  0 siblings, 1 reply; 19+ messages in thread
From: Kewen.Lin @ 2024-05-09  5:37 UTC (permalink / raw)
  To: sgk, Mikael Morin
  Cc: GCC Patches, fortran, Jakub Jelinek, Segher Boessenkool,
	Peter Bergner, David Edelsohn

Hi,

on 2024/5/9 06:01, Steve Kargl wrote:
> On Wed, May 08, 2024 at 01:27:53PM +0800, Kewen.Lin wrote:
>>
>> Previously effective target fortran_real_c_float128 never
>> passes on Power regardless of the default 128 long double
>> is ibmlongdouble or ieeelongdouble.  It's due to that TF
>> mode is always used for kind 16 real, which has precision
>> 127, while the node float128_type_node for c_float128 has
>> 128 type precision, get_real_kind_from_node can't find a
>> matching as it only checks gfc_real_kinds[i].mode_precision
>> and type precision.
>>
>> With changing TFmode/IFmode/KFmode to have the same mode
>> precision 128, now fortran_real_c_float12 can pass with
>> ieeelongdouble enabled by default and test cases guarded
>> with it get tested accordingly.  But with ibmlongdouble
>> enabled by default, since TFmode has precision 128 which
>> is the same as type precision 128 of float128_type_node,
>> get_real_kind_from_node considers kind for TFmode matches
>> float128_type_node, but it's wrong as at this time point
>> TFmode is with ibm extended format.  So this patch is to
>> teach get_real_kind_from_node to check one more field which
>> can be differentiable from the underlying real format, it
>> can avoid the unexpected matching when there more than one
>> modes have the same precision.
>>
>> Bootstrapped and regress-tested on:
>>   - powerpc64-linux-gnu P8/P9 (with ibm128 by default)
>>   - powerpc64le-linux-gnu P9/P10 (with ibm128 by default)
>>   - powerpc64le-linux-gnu P9 (with ieee128 by default)
>>
>> BR,
>> Kewen
>> -----
>> 	PR target/112993
>>

> OK from the fortran point of view.
> Thanks.

> 
> First, I have no issue with Mikael's OK for committing the
> patch. 

Thanks to both!

> 
> That said, Fortran has the concept of model numbers, which
> are set in arith.c.  Does this change give the expected 
> value for ibm128?  For example, with "REAL(16) X", one
> has "DIGITS(X) = 113", which is the precision on the 
> of the underlying IEEE754 binary128 type.
> 

With some testings locally, I noticed that currently DIGITS has
been already correct even without this change.  For "REAL(16) X",
with -mabi=ibmlongdouble it's long double with ibm128 format and
its DIGITS(X) is 106, while with -mabi=ieeelongdouble it's long
double with ieee128 format and its DIGITS(X) is 113.

BR,
Kewen


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 2/4] fortran: Teach get_real_kind_from_node for Power 128 fp modes [PR112993]g
  2024-05-09  5:37     ` Kewen.Lin
@ 2024-05-09 16:47       ` Steve Kargl
  0 siblings, 0 replies; 19+ messages in thread
From: Steve Kargl @ 2024-05-09 16:47 UTC (permalink / raw)
  To: Kewen.Lin
  Cc: Mikael Morin, GCC Patches, fortran, Jakub Jelinek,
	Segher Boessenkool, Peter Bergner, David Edelsohn

On Thu, May 09, 2024 at 01:37:32PM +0800, Kewen.Lin wrote:
> 
> > 
> > That said, Fortran has the concept of model numbers, which
> > are set in arith.c.  Does this change give the expected 
> > value for ibm128?  For example, with "REAL(16) X", one
> > has "DIGITS(X) = 113", which is the precision on the 
> > of the underlying IEEE754 binary128 type.
> > 
> 
> With some testings locally, I noticed that currently DIGITS has
> been already correct even without this change.  For "REAL(16) X",
> with -mabi=ibmlongdouble it's long double with ibm128 format and
> its DIGITS(X) is 106, while with -mabi=ieeelongdouble it's long
> double with ieee128 format and its DIGITS(X) is 113.
> 

That's good.  I'll take a look later this weekend
at arith.c.  There are few others to consider:
precision(x), minexponent(x), maxexponent(x), huge(x),
and tiny(x).

-- 
Steve

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/4] rs6000: Make all 128 bit scalar FP modes have 128 bit precision [PR112993]
  2024-05-08  5:21 [PATCH 1/4] rs6000: Make all 128 bit scalar FP modes have 128 bit precision [PR112993] Kewen.Lin
                   ` (2 preceding siblings ...)
  2024-05-08  5:36 ` [PATCH 4/4] tree: Remove KFmode workaround [PR112993] Kewen.Lin
@ 2024-05-09 19:12 ` Joseph Myers
  2024-05-10  6:31   ` Richard Biener
  3 siblings, 1 reply; 19+ messages in thread
From: Joseph Myers @ 2024-05-09 19:12 UTC (permalink / raw)
  To: Kewen.Lin
  Cc: GCC Patches, Jakub Jelinek, Richard Biener, Richard Sandiford,
	Segher Boessenkool, Peter Bergner, Michael Meissner,
	David Edelsohn

On Wed, 8 May 2024, Kewen.Lin wrote:

> to widen IFmode to TFmode.  To make build_common_tree_nodes
> be able to find the correct mode for long double type node,
> it introduces one hook mode_for_longdouble to offer target
> a way to specify the mode used for long double type node.

I don't really like layering a hook on top of the old target macro as a 
way to address a deficiency in the design of that target macro (floating 
types should have their mode, not a poorly defined precision value, 
specified directly by the target).

A better hook design might be something like mode_for_floating_type (enum 
tree_index), where the argument is TI_FLOAT_TYPE, TI_DOUBLE_TYPE or 
TI_LONG_DOUBLE_TYPE, replacing all definitions and uses of 
FLOAT_TYPE_SIZE, DOUBLE_TYPE_SIZE and LONG_DOUBLE_TYPE_SIZE with the 
single new hook and appropriate definitions for each target (with a 
default definition that uses SFmode for float and DFmode for double and 
long double, which would be suitable for many targets).

-- 
Joseph S. Myers
josmyers@redhat.com


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/4] rs6000: Make all 128 bit scalar FP modes have 128 bit precision [PR112993]
  2024-05-09 19:12 ` [PATCH 1/4] rs6000: Make all 128 bit scalar FP modes have 128 bit precision [PR112993] Joseph Myers
@ 2024-05-10  6:31   ` Richard Biener
  2024-05-13  1:39     ` Kewen.Lin
  0 siblings, 1 reply; 19+ messages in thread
From: Richard Biener @ 2024-05-10  6:31 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Kewen.Lin, GCC Patches, Jakub Jelinek, Richard Sandiford,
	Segher Boessenkool, Peter Bergner, Michael Meissner,
	David Edelsohn

On Thu, May 9, 2024 at 9:12 PM Joseph Myers <josmyers@redhat.com> wrote:
>
> On Wed, 8 May 2024, Kewen.Lin wrote:
>
> > to widen IFmode to TFmode.  To make build_common_tree_nodes
> > be able to find the correct mode for long double type node,
> > it introduces one hook mode_for_longdouble to offer target
> > a way to specify the mode used for long double type node.
>
> I don't really like layering a hook on top of the old target macro as a
> way to address a deficiency in the design of that target macro (floating
> types should have their mode, not a poorly defined precision value,
> specified directly by the target).

Seconded.

> A better hook design might be something like mode_for_floating_type (enum
> tree_index), where the argument is TI_FLOAT_TYPE, TI_DOUBLE_TYPE or
> TI_LONG_DOUBLE_TYPE, replacing all definitions and uses of
> FLOAT_TYPE_SIZE, DOUBLE_TYPE_SIZE and LONG_DOUBLE_TYPE_SIZE with the
> single new hook and appropriate definitions for each target (with a
> default definition that uses SFmode for float and DFmode for double and
> long double, which would be suitable for many targets).

In fact replacing all of X_TYPE_SIZE with a single hook might be worthwhile
though this removes the "convenient" defaulting, requiring each target to
enumerate all standard C ABI type modes.  But that might be also a good thing.

The most pragmatic solution would be to do
s/LONG_DOUBLE_TYPE_SIZE/LONG_DOUBLE_TYPE_MODE/

Richard.

> --
> Joseph S. Myers
> josmyers@redhat.com
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/4] rs6000: Make all 128 bit scalar FP modes have 128 bit precision [PR112993]
  2024-05-10  6:31   ` Richard Biener
@ 2024-05-13  1:39     ` Kewen.Lin
  2024-05-13  7:11       ` Richard Biener
  2024-05-13 13:18       ` Joseph Myers
  0 siblings, 2 replies; 19+ messages in thread
From: Kewen.Lin @ 2024-05-13  1:39 UTC (permalink / raw)
  To: Richard Biener, Joseph Myers
  Cc: GCC Patches, Jakub Jelinek, Richard Sandiford,
	Segher Boessenkool, Peter Bergner, Michael Meissner,
	David Edelsohn

Hi Joseph and Richi,

Thanks for the suggestions and comments!

on 2024/5/10 14:31, Richard Biener wrote:
> On Thu, May 9, 2024 at 9:12 PM Joseph Myers <josmyers@redhat.com> wrote:
>>
>> On Wed, 8 May 2024, Kewen.Lin wrote:
>>
>>> to widen IFmode to TFmode.  To make build_common_tree_nodes
>>> be able to find the correct mode for long double type node,
>>> it introduces one hook mode_for_longdouble to offer target
>>> a way to specify the mode used for long double type node.
>>
>> I don't really like layering a hook on top of the old target macro as a
>> way to address a deficiency in the design of that target macro (floating
>> types should have their mode, not a poorly defined precision value,
>> specified directly by the target).

Good point!

> 
> Seconded.
> 
>> A better hook design might be something like mode_for_floating_type (enum
>> tree_index), where the argument is TI_FLOAT_TYPE, TI_DOUBLE_TYPE or
>> TI_LONG_DOUBLE_TYPE, replacing all definitions and uses of
>> FLOAT_TYPE_SIZE, DOUBLE_TYPE_SIZE and LONG_DOUBLE_TYPE_SIZE with the
>> single new hook and appropriate definitions for each target (with a
>> default definition that uses SFmode for float and DFmode for double and
>> long double, which would be suitable for many targets).
> 

The originally proposed hook was meant to make the other ports unaffected,
but I agree that introducing such hook would be more clear.

> In fact replacing all of X_TYPE_SIZE with a single hook might be worthwhile
> though this removes the "convenient" defaulting, requiring each target to
> enumerate all standard C ABI type modes.  But that might be also a good thing.
> 

I guess the main value by extending from floating point types to all is to
unify them?  (Assuming that excepting for floating types the others would
not have multiple possible representations like what we faces on 128bit fp).

> The most pragmatic solution would be to do
> s/LONG_DOUBLE_TYPE_SIZE/LONG_DOUBLE_TYPE_MODE/

Yeah, this beats my proposed hook (assuming the default is VOIDmode too).

So it seems we have three alternatives here:
  1) s/LONG_DOUBLE_TYPE_SIZE/LONG_DOUBLE_TYPE_MODE/
  2) mode_for_floating_type
  3) mode_for_abi_type

Since 1) would make long double type special (different from the other types
having _TYPE_SIZE), personally I'm inclined to 3): implement 2) first, get
this patch series landed, extend to all.

Do you have any preference?  

BR,
Kewen

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/4] rs6000: Make all 128 bit scalar FP modes have 128 bit precision [PR112993]
  2024-05-13  1:39     ` Kewen.Lin
@ 2024-05-13  7:11       ` Richard Biener
  2024-05-13 13:18       ` Joseph Myers
  1 sibling, 0 replies; 19+ messages in thread
From: Richard Biener @ 2024-05-13  7:11 UTC (permalink / raw)
  To: Kewen.Lin
  Cc: Joseph Myers, GCC Patches, Jakub Jelinek, Richard Sandiford,
	Segher Boessenkool, Peter Bergner, Michael Meissner,
	David Edelsohn

On Mon, May 13, 2024 at 3:39 AM Kewen.Lin <linkw@linux.ibm.com> wrote:
>
> Hi Joseph and Richi,
>
> Thanks for the suggestions and comments!
>
> on 2024/5/10 14:31, Richard Biener wrote:
> > On Thu, May 9, 2024 at 9:12 PM Joseph Myers <josmyers@redhat.com> wrote:
> >>
> >> On Wed, 8 May 2024, Kewen.Lin wrote:
> >>
> >>> to widen IFmode to TFmode.  To make build_common_tree_nodes
> >>> be able to find the correct mode for long double type node,
> >>> it introduces one hook mode_for_longdouble to offer target
> >>> a way to specify the mode used for long double type node.
> >>
> >> I don't really like layering a hook on top of the old target macro as a
> >> way to address a deficiency in the design of that target macro (floating
> >> types should have their mode, not a poorly defined precision value,
> >> specified directly by the target).
>
> Good point!
>
> >
> > Seconded.
> >
> >> A better hook design might be something like mode_for_floating_type (enum
> >> tree_index), where the argument is TI_FLOAT_TYPE, TI_DOUBLE_TYPE or
> >> TI_LONG_DOUBLE_TYPE, replacing all definitions and uses of
> >> FLOAT_TYPE_SIZE, DOUBLE_TYPE_SIZE and LONG_DOUBLE_TYPE_SIZE with the
> >> single new hook and appropriate definitions for each target (with a
> >> default definition that uses SFmode for float and DFmode for double and
> >> long double, which would be suitable for many targets).
> >
>
> The originally proposed hook was meant to make the other ports unaffected,
> but I agree that introducing such hook would be more clear.
>
> > In fact replacing all of X_TYPE_SIZE with a single hook might be worthwhile
> > though this removes the "convenient" defaulting, requiring each target to
> > enumerate all standard C ABI type modes.  But that might be also a good thing.
> >
>
> I guess the main value by extending from floating point types to all is to
> unify them?  (Assuming that excepting for floating types the others would
> not have multiple possible representations like what we faces on 128bit fp).
>
> > The most pragmatic solution would be to do
> > s/LONG_DOUBLE_TYPE_SIZE/LONG_DOUBLE_TYPE_MODE/
>
> Yeah, this beats my proposed hook (assuming the default is VOIDmode too).
>
> So it seems we have three alternatives here:
>   1) s/LONG_DOUBLE_TYPE_SIZE/LONG_DOUBLE_TYPE_MODE/
>   2) mode_for_floating_type
>   3) mode_for_abi_type
>
> Since 1) would make long double type special (different from the other types
> having _TYPE_SIZE), personally I'm inclined to 3): implement 2) first, get
> this patch series landed, extend to all.
>
> Do you have any preference?

Maybe do 3) but have the default hook implementation look at
*_TYPE_SIZE when the target doesn't implement the hook?  That would
force you to transition rs6000 away from *_TYPE_SIZE completely
but this would also prove the design.

Btw, for .c.mode_for_abi_type I'd exclude ADA_LONG_TYPE_SIZE.

Joseph, do you agree with this?  I'd not touch the target macros like
PTRDIFF_TYPE (those evaluating to a string) at this point though
they could be handled with a common target hook as well (not sure
if we'd want to have a unified hook for both?).

Thanks,
Richard.

>
> BR,
> Kewen

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/4] rs6000: Make all 128 bit scalar FP modes have 128 bit precision [PR112993]
  2024-05-13  1:39     ` Kewen.Lin
  2024-05-13  7:11       ` Richard Biener
@ 2024-05-13 13:18       ` Joseph Myers
  2024-05-24 10:19         ` [RFC/PATCH] Replace {FLOAT,{,LONG_}DOUBLE}_TYPE_SIZE with new hook Kewen.Lin
  1 sibling, 1 reply; 19+ messages in thread
From: Joseph Myers @ 2024-05-13 13:18 UTC (permalink / raw)
  To: Kewen.Lin
  Cc: Richard Biener, GCC Patches, Jakub Jelinek, Richard Sandiford,
	Segher Boessenkool, Peter Bergner, Michael Meissner,
	David Edelsohn

On Mon, 13 May 2024, Kewen.Lin wrote:

> > In fact replacing all of X_TYPE_SIZE with a single hook might be worthwhile
> > though this removes the "convenient" defaulting, requiring each target to
> > enumerate all standard C ABI type modes.  But that might be also a good thing.
> > 
> 
> I guess the main value by extending from floating point types to all is to
> unify them?  (Assuming that excepting for floating types the others would
> not have multiple possible representations like what we faces on 128bit fp).

For integer types, giving the number of bits makes sense as an interface - 
there isn't an issue with different modes.

So I think it's appropriate for floating and integer types to have 
separate hooks - with the one for floating types returning a mode, and the 
one for integer types returning a number of bits.  (And also keep the 
existing separate hook for _FloatN / _FloatNx modes.)

That may also make for more convenient defaults (whether a target has long 
double wider than double is largely independent of what sizes it uses for 
integer types).

-- 
Joseph S. Myers
josmyers@redhat.com


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC/PATCH] Replace {FLOAT,{,LONG_}DOUBLE}_TYPE_SIZE with new hook
  2024-05-13 13:18       ` Joseph Myers
@ 2024-05-24 10:19         ` Kewen.Lin
  2024-05-24 12:23           ` Richard Biener
  2024-05-28 21:06           ` Joseph Myers
  0 siblings, 2 replies; 19+ messages in thread
From: Kewen.Lin @ 2024-05-24 10:19 UTC (permalink / raw)
  To: Joseph Myers, Richard Biener
  Cc: GCC Patches, Jakub Jelinek, Richard Sandiford,
	Segher Boessenkool, Peter Bergner, Michael Meissner,
	David Edelsohn

[-- Attachment #1: Type: text/plain, Size: 2193 bytes --]

Hi Joseph and Richi,

on 2024/5/13 21:18, Joseph Myers wrote:
> On Mon, 13 May 2024, Kewen.Lin wrote:
> 
>>> In fact replacing all of X_TYPE_SIZE with a single hook might be worthwhile
>>> though this removes the "convenient" defaulting, requiring each target to
>>> enumerate all standard C ABI type modes.  But that might be also a good thing.
>>>
>>
>> I guess the main value by extending from floating point types to all is to
>> unify them?  (Assuming that excepting for floating types the others would
>> not have multiple possible representations like what we faces on 128bit fp).
> 
> For integer types, giving the number of bits makes sense as an interface - 
> there isn't an issue with different modes.
> 
> So I think it's appropriate for floating and integer types to have 
> separate hooks - with the one for floating types returning a mode, and the 
> one for integer types returning a number of bits.  (And also keep the 
> existing separate hook for _FloatN / _FloatNx modes.)
> 
> That may also make for more convenient defaults (whether a target has long 
> double wider than double is largely independent of what sizes it uses for 
> integer types).
> 

Following your suggestion and comments, I made this patch
for mode_for_floating_type first, considering this touches
a few FE and port specific code, I think I have to split
it into a patch series.  Before making that, I'd like to
ensure this meets what you expected, and also seek for the
suggestion on how to organize the sub-patches.  There seem
two ways for sub-patches:
  1) split this into pieces according to FEs and ports, and
     squash all of them and commit one patch.
  2) extract all hook implementation as 1st series (split
     as ports);
     extract the hook enablement as 2nd part (split as
     generic and FEs);
     the remaining is to remove useless macros (split it
     as generic and ports);

The 1) is straightforward, while the 2) is fine-grained and
easy for isolation, but not sure if it's worth doing.

btw, the attached patch is bootstrapped and regtested on
powerpc64-linux-gnu and powerpc64le-linux-gnu with all
languages on, cross cc1 built well for affected ports.

BR,
Kewen

-----

[-- Attachment #2: 0001-Replace-FLOAT-LONG_-DOUBLE-_TYPE_SIZE-with-new-hook-.patch --]
[-- Type: text/plain, Size: 79832 bytes --]

From 2935750160f4eaf72eb7fba5832c99d6bf552862 Mon Sep 17 00:00:00 2001
From: Kewen Lin <linkw@linux.ibm.com>
Date: Fri, 24 May 2024 00:10:22 -0500
Subject: [PATCH] Replace {FLOAT,{,LONG_}DOUBLE}_TYPE_SIZE with new hook
 mode_for_floating_type

Currently how we determine which mode will be used for a
floating point type is that for a given type precision
(size) call mode_for_size to get the first mode which has
this size in the specified class.  On Powerpc, we have
three modes (TF/KF/IF) having the same mode precision 128
(see[1]), so the processing forces us to have to place TF
at the first place, it would require us to make more
adjustment in some generic code to avoid some unexpected
mode conversions and it would be even worse if we get rid
of TF eventually one day.  And as Joseph pointed out in [2],
"floating  types should have their mode, not a poorly
defined precision value", as Joseph and Richi suggested,
this patch is to introduce one hook mode_for_floating_type
which returns the corresponding mode for type float, double
or long double.  The default implementation returns SFmode
for float and DFmode for double or long double, and ports
which need special treatment have their own port specific
implementation (referring to {,LONG_}DOUBLE_TYPE_SIZE).
For all generic uses of {FLOAT,{,LONG_}DOUBLE}_TYPE_SIZE,
depending on the context, it replaces them with
TYPE_PRECISION of the according type node, or
GET_MODE_PRECISION on the mode from mode_for_floating_type.
It also removes some useless uses of
{FLOAT,{,LONG_}DOUBLE}_TYPE_SIZE in target specific codes,
but leaves those being used (like defining other macros)
untouched.

[1] https://gcc.gnu.org/pipermail/gcc-patches/2024-May/651017.html
[2] https://gcc.gnu.org/pipermail/gcc-patches/2024-May/651209.html

gcc/ada/ChangeLog:

	* gcc-interface/decl.cc (gnat_to_gnu_entity): Use TYPE_PRECISION of
	long_double_type_node to replace LONG_DOUBLE_TYPE_SIZE.

gcc/ChangeLog:

	* config/aarch64/aarch64.cc (aarch64_c_mode_for_floating_type):
	New function.
	(TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
	* config/aarch64/aarch64.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/alpha/alpha.cc (alpha_c_mode_for_floating_type): New
	function.
	(TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
	* config/alpha/alpha.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/arc/arc.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/avr/avr.cc (avr_c_mode_for_floating_type): New
	function.
	(TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
	* config/avr/avr.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/bpf/bpf.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/epiphany/epiphany.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/fr30/fr30.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/frv/frv.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/ft32/ft32.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/gcn/gcn.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/h8300/h8300.cc (h8300_c_mode_for_floating_type): New
	function.
	(TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
	* config/i386/i386.cc (ix86_c_mode_for_floating_type): New
	function.
	(TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
	* config/i386/i386.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/ia64/ia64.cc (ia64_c_mode_for_floating_type): New
	function.
	(TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
	* config/ia64/ia64.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/iq2000/iq2000.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/lm32/lm32.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/loongarch/loongarch.cc (loongarch_c_mode_for_floating_type):
	New function.
	(TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
	* config/m32c/m32c.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/m32r/m32r.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/m68k/m68k.cc (m68k_c_mode_for_floating_type): New function.
	(TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
	* config/microblaze/microblaze.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/mips/mips.cc (mips_c_mode_for_floating_type): New function.
	(TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
	* config/mmix/mmix.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/moxie/moxie.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/msp430/msp430.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/nds32/nds32.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/nios2/nios2.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/nvptx/nvptx.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/or1k/or1k.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/pa/pa-hpux.h (LONG_DOUBLE_TYPE_SIZE): Undef it before
	re-define it.
	* config/pa/pa.h (FLOAT_TYPE_SIZE): New macro.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/pa/pa.cc (pa_c_mode_for_floating_type): New function.
	(TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
	* config/pdp11/pdp11.h (LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/pru/pru.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/riscv/riscv.cc (riscv_c_mode_for_floating_type): New function.
	(TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
	* config/riscv/riscv.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/rl78/rl78.cc (TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
	(rl78_c_mode_for_floating_type): New function.
	* config/rl78/rl78.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/rs6000/rs6000.cc (TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
	(rs6000_c_mode_for_floating_type): New function.
	* config/rs6000/rs6000.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/rx/rx.cc (rx_c_mode_for_floating_type): New function.
	(TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
	* config/rx/rx.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/s390/s390.cc (s390_c_mode_for_floating_type): New function.
	(TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
	* config/s390/s390.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/sh/sh.cc (sh_c_mode_for_floating_type): New function.
	(TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
	* config/sh/sh.h (LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/sparc/sparc.cc (sparc_c_mode_for_floating_type): New function.
	(TARGET_C_MODE_FOR_FLOATING_TYPE): New macro.
	(FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	* config/stormy16/stormy16.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/visium/visium.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/xtensa/xtensa.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* config/darwin.cc (darwin_patch_builtins): Use TYPE_PRECISION of
	long_double_type_node to replace LONG_DOUBLE_TYPE_SIZE.
	* config/vms/vms.cc (vms_patch_builtins): Likewise.
	* coretypes.h (enum tree_index): Forward declaration.
	* defaults.h (FLOAT_TYPE_SIZE): Remove.
	(DOUBLE_TYPE_SIZE): Likewise.
	(LONG_DOUBLE_TYPE_SIZE): Likewise.
	* doc/rtl.texi: Update document by replacing {FLOAT,DOUBLE}_TYPE_SIZE
	with C type {float, double}.
	* doc/tm.texi: Regenerate.
	* doc/tm.texi.in: Document new hook mode_for_floating_type, remove
	document entries for {FLOAT,DOUBLE,LONG_DOUBLE}_TYPE_SIZE and
	update document for WIDEST_HARDWARE_FP_SIZE.
	* emit-rtl.cc (init_emit_once): Replace DOUBLE_TYPE_SIZE by
	calling targetm.c.mode_for_floating_type with TI_DOUBLE_TYPE.
	* real.h (REAL_VALUE_TO_TARGET_LONG_DOUBLE): Use TYPE_PRECISION of
	long_double_type_node to replace LONG_DOUBLE_TYPE_SIZE.
	* target.def (mode_for_floating_type): New hook.
	* targhooks.cc (default_mode_for_floating_type): New function.
	(default_scalar_mode_supported_p): Update macros
	{FLOAT,DOUBLE,LONG_DOUBLE}_TYPE_SIZE by calling
	targetm.c.mode_for_floating_type with
	TI_{FLOAT,DOUBLE,LONG_DOUBLE}_TYPE.
	* targhooks.h (default_mode_for_floating_type): New declaration.
	* tree-core.h (enum tree_index): Specify underlying type unsigned
	to sync with forward declaration in coretypes.h.
	(NUM_FLOATN_TYPES): Explicitly convert to int.
	(NUM_FLOATNX_TYPES): Likewise.
	(NUM_FLOATN_NX_TYPES): Likewise.
	* tree.cc (build_common_tree_nodes): Update macros
	{FLOAT,DOUBLE,LONG_DOUBLE}_TYPE_SIZE by calling
	targetm.c.mode_for_floating_type with
	TI_{FLOAT,DOUBLE,LONG_DOUBLE}_TYPE and set type mode accordingly.

gcc/d/ChangeLog:

	* d-target.cc (Target::_init): Use TYPE_PRECISION of
	long_double_type_node to replace LONG_DOUBLE_TYPE_SIZE.

gcc/fortran/ChangeLog:

	* trans-intrinsic.cc (build_round_expr): Likewise.
	* trans-types.cc (gfc_build_real_type): Use TYPE_PRECISION of
	{float,double,long_double}_type_node to replace
	{FLOAT,DOUBLE,LONG_DOUBLE}_TYPE_SIZE.

gcc/go/ChangeLog:

	* go-gcc.cc (Gcc_backend::float_type): Likewise.
	(Gcc_backend::complex_type): Likewise.

gcc/rust/ChangeLog:

	* rust-gcc.cc (float_type): Likewise.

gcc/jit/ChangeLog:

	* jit-recording.cc (recording::memento_of_get_type::get_size): Update
	macros {FLOAT,DOUBLE,LONG_DOUBLE}_TYPE_SIZE by calling
	targetm.c.mode_for_floating_type with
	TI_{FLOAT,DOUBLE,LONG_DOUBLE}_TYPE.

gcc/m2/ChangeLog:

	* gm2-gcc/m2type.cc (build_m2_short_real_node): Use TYPE_PRECISION of
	float_type_node to replace FLOAT_TYPE_SIZE.
	(build_m2_real_node): Use TYPE_PRECISION of double_type_node to
	replace DOUBLE_TYPE_SIZE.
	(build_m2_long_real_node): Use TYPE_PRECISION of
	long_double_type_node to replace LONG_DOUBLE_TYPE_SIZE.
---
 gcc/ada/gcc-interface/decl.cc      |  3 ++-
 gcc/config/aarch64/aarch64.cc      | 15 ++++++++++++++
 gcc/config/aarch64/aarch64.h       |  6 ------
 gcc/config/alpha/alpha.cc          | 17 ++++++++++++++-
 gcc/config/alpha/alpha.h           |  8 --------
 gcc/config/arc/arc.h               |  3 ---
 gcc/config/avr/avr.cc              | 17 +++++++++++++++
 gcc/config/avr/avr.h               |  3 ---
 gcc/config/bpf/bpf.h               |  3 ---
 gcc/config/darwin.cc               |  2 +-
 gcc/config/epiphany/epiphany.h     |  3 ---
 gcc/config/fr30/fr30.h             |  3 ---
 gcc/config/frv/frv.h               |  3 ---
 gcc/config/ft32/ft32.h             |  4 ----
 gcc/config/gcn/gcn.h               |  3 ---
 gcc/config/h8300/h8300.cc          | 15 ++++++++++++++
 gcc/config/i386/i386.cc            | 15 ++++++++++++++
 gcc/config/i386/i386.h             |  4 ----
 gcc/config/ia64/ia64.cc            | 18 ++++++++++++++++
 gcc/config/ia64/ia64.h             | 12 -----------
 gcc/config/iq2000/iq2000.h         |  3 ---
 gcc/config/lm32/lm32.h             |  4 ----
 gcc/config/loongarch/loongarch.cc  | 15 ++++++++++++++
 gcc/config/m32c/m32c.h             |  4 ----
 gcc/config/m32r/m32r.h             |  3 ---
 gcc/config/m68k/m68k.cc            | 16 +++++++++++++++
 gcc/config/microblaze/microblaze.h |  3 ---
 gcc/config/mips/mips.cc            | 14 +++++++++++++
 gcc/config/mmix/mmix.h             |  4 ----
 gcc/config/moxie/moxie.h           |  4 ----
 gcc/config/msp430/msp430.h         |  4 ----
 gcc/config/nds32/nds32.h           |  4 ----
 gcc/config/nios2/nios2.h           |  3 ---
 gcc/config/nvptx/nvptx.h           |  3 ---
 gcc/config/or1k/or1k.h             |  3 ---
 gcc/config/pa/pa-hpux.h            |  1 +
 gcc/config/pa/pa.cc                | 15 ++++++++++++++
 gcc/config/pa/pa.h                 |  5 +++++
 gcc/config/pdp11/pdp11.h           | 11 ----------
 gcc/config/pru/pru.h               |  3 ---
 gcc/config/riscv/riscv.cc          | 15 ++++++++++++++
 gcc/config/riscv/riscv.h           |  4 ----
 gcc/config/rl78/rl78.cc            | 15 ++++++++++++++
 gcc/config/rl78/rl78.h             |  4 ----
 gcc/config/rs6000/rs6000.cc        | 16 +++++++++++++++
 gcc/config/rs6000/rs6000.h         | 14 -------------
 gcc/config/rx/rx.cc                | 15 ++++++++++++++
 gcc/config/rx/rx.h                 |  4 ----
 gcc/config/s390/s390.cc            | 15 ++++++++++++++
 gcc/config/s390/s390.h             |  3 ---
 gcc/config/sh/sh.cc                | 18 ++++++++++++++++
 gcc/config/sh/sh.h                 | 10 ---------
 gcc/config/sparc/sparc.cc          | 24 ++++++++++++++--------
 gcc/config/stormy16/stormy16.h     |  6 ------
 gcc/config/visium/visium.h         | 29 ++++++--------------------
 gcc/config/vms/vms.cc              |  5 +++--
 gcc/config/xtensa/xtensa.h         |  3 ---
 gcc/coretypes.h                    |  1 +
 gcc/d/d-target.cc                  |  3 ++-
 gcc/defaults.h                     | 12 -----------
 gcc/doc/rtl.texi                   |  2 +-
 gcc/doc/tm.texi                    | 33 ++++++++++++------------------
 gcc/doc/tm.texi.in                 | 27 +++++++-----------------
 gcc/emit-rtl.cc                    |  3 ++-
 gcc/fortran/trans-intrinsic.cc     |  3 ++-
 gcc/fortran/trans-types.cc         | 10 +++++----
 gcc/go/go-gcc.cc                   | 12 +++++------
 gcc/jit/jit-recording.cc           | 12 +++++++----
 gcc/m2/gm2-gcc/m2type.cc           |  6 +++---
 gcc/real.h                         |  7 ++++---
 gcc/rust/rust-gcc.cc               |  6 +++---
 gcc/target.def                     |  9 ++++++++
 gcc/targhooks.cc                   | 18 +++++++++++++---
 gcc/targhooks.h                    |  1 +
 gcc/tree-core.h                    | 13 ++++++------
 gcc/tree.cc                        | 18 +++++++++++++---
 76 files changed, 389 insertions(+), 286 deletions(-)

diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc
index ca174bff009..5b05a5f80e2 100644
--- a/gcc/ada/gcc-interface/decl.cc
+++ b/gcc/ada/gcc-interface/decl.cc
@@ -519,7 +519,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
 	  esize = UI_To_Int (Esize (gnat_entity));
 
 	  if (IN (kind, Float_Kind))
-	    max_esize = fp_prec_to_size (LONG_DOUBLE_TYPE_SIZE);
+	    max_esize
+	      = fp_prec_to_size (TYPE_PRECISION (long_double_type_node));
 	  else if (IN (kind, Access_Kind))
 	    max_esize = POINTER_SIZE * 2;
 	  else
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 662ff5a9b0c..9f64fdf757e 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -28413,6 +28413,18 @@ aarch64_bitint_type_info (int n, struct bitint_info *info)
   return true;
 }
 
+/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return TFmode for
+   TI_LONG_DOUBLE_TYPE which is for long double type, go with the default
+   one for the others.  */
+
+static machine_mode
+aarch64_c_mode_for_floating_type (enum tree_index ti)
+{
+  if (ti == TI_LONG_DOUBLE_TYPE)
+    return TFmode;
+  return default_mode_for_floating_type (ti);
+}
+
 /* Implement TARGET_SCHED_CAN_SPECULATE_INSN.  Return true if INSN can be
    scheduled for speculative execution.  Reject the long-running division
    and square-root instructions.  */
@@ -30540,6 +30552,9 @@ aarch64_run_selftests (void)
 #undef TARGET_C_BITINT_TYPE_INFO
 #define TARGET_C_BITINT_TYPE_INFO aarch64_bitint_type_info
 
+#undef TARGET_C_MODE_FOR_FLOATING_TYPE
+#define TARGET_C_MODE_FOR_FLOATING_TYPE aarch64_c_mode_for_floating_type
+
 #undef  TARGET_EXPAND_BUILTIN
 #define TARGET_EXPAND_BUILTIN aarch64_expand_builtin
 
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index bbf11faaf4b..2064c23f961 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -96,12 +96,6 @@
 
 #define LONG_LONG_TYPE_SIZE	64
 
-#define FLOAT_TYPE_SIZE		32
-
-#define DOUBLE_TYPE_SIZE	64
-
-#define LONG_DOUBLE_TYPE_SIZE	128
-
 /* This value is the amount of bytes a caller is allowed to drop the stack
    before probing has to be done for stack clash protection.  */
 #define STACK_CLASH_CALLER_GUARD 1024
diff --git a/gcc/config/alpha/alpha.cc b/gcc/config/alpha/alpha.cc
index 1126cea1f7b..a6fe95e7177 100644
--- a/gcc/config/alpha/alpha.cc
+++ b/gcc/config/alpha/alpha.cc
@@ -9916,7 +9916,19 @@ alpha_can_change_mode_class (machine_mode from, machine_mode to,
   return (GET_MODE_SIZE (from) == GET_MODE_SIZE (to)
 	  || !reg_classes_intersect_p (FLOAT_REGS, rclass));
 }
-\f
+
+/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return TFmode or DFmode
+   for TI_LONG_DOUBLE_TYPE which is for long double type, go with the
+   default one for the others.  */
+
+static machine_mode
+alpha_c_mode_for_floating_type (enum tree_index ti)
+{
+  if (ti == TI_LONG_DOUBLE_TYPE)
+    return TARGET_LONG_DOUBLE_128 ? TFmode : DFmode;
+  return default_mode_for_floating_type (ti);
+}
+
 /* Initialize the GCC target structure.  */
 #if TARGET_ABI_OPEN_VMS
 # undef TARGET_ATTRIBUTE_TABLE
@@ -10123,6 +10135,9 @@ alpha_can_change_mode_class (machine_mode from, machine_mode to,
 #undef TARGET_CAN_CHANGE_MODE_CLASS
 #define TARGET_CAN_CHANGE_MODE_CLASS alpha_can_change_mode_class
 
+#undef TARGET_C_MODE_FOR_FLOATING_TYPE
+#define TARGET_C_MODE_FOR_FLOATING_TYPE alpha_c_mode_for_floating_type
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 \f
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index 25ccfce96b8..ee9e0918038 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -195,14 +195,6 @@ extern enum alpha_fp_trap_mode alpha_fptm;
 /* Define the size of `long long'.  The default is the twice the word size.  */
 #define LONG_LONG_TYPE_SIZE 64
 
-/* The two floating-point formats we support are S-floating, which is
-   4 bytes, and T-floating, which is 8 bytes.  `float' is S and `double'
-   and `long double' are T.  */
-
-#define FLOAT_TYPE_SIZE 32
-#define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
-
 /* Work around target_flags dependency in ada/targtyps.cc.  */
 #define WIDEST_HARDWARE_FP_SIZE 64
 
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index f3b43882671..0a1ecb71d89 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -296,9 +296,6 @@ if (GET_MODE_CLASS (MODE) == MODE_INT		\
 #define INT_TYPE_SIZE		32
 #define LONG_TYPE_SIZE		32
 #define LONG_LONG_TYPE_SIZE	64
-#define FLOAT_TYPE_SIZE		32
-#define DOUBLE_TYPE_SIZE	64
-#define LONG_DOUBLE_TYPE_SIZE	64
 
 /* Define this as 1 if `char' should by default be signed; else as 0.  */
 #define DEFAULT_SIGNED_CHAR 0
diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index 74924ab0565..61c325f2497 100644
--- a/gcc/config/avr/avr.cc
+++ b/gcc/config/avr/avr.cc
@@ -6930,6 +6930,20 @@ avr_canonicalize_comparison (int *icode, rtx *op0, rtx *op1, bool op0_fixed)
     }
 }
 
+/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return SFmode or DFmode
+   for TI_{LONG_,}DOUBLE_TYPE which is for {long,} double type, go with
+   the default one for the others.  */
+
+static machine_mode
+avr_c_mode_for_floating_type (enum tree_index ti)
+{
+  if (ti == TI_DOUBLE_TYPE)
+    return avr_double == 32 ? SFmode : DFmode;
+  if (ti == TI_LONG_DOUBLE_TYPE)
+    return avr_long_double == 32 ? SFmode : DFmode;
+  return default_mode_for_floating_type (ti);
+}
+
 
 /* Output compare instruction
 
@@ -16411,6 +16425,9 @@ avr_float_lib_compare_returns_bool (machine_mode mode, enum rtx_code)
 #undef  TARGET_HAVE_SPECULATION_SAFE_VALUE
 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
 
+#undef TARGET_C_MODE_FOR_FLOATING_TYPE
+#define TARGET_C_MODE_FOR_FLOATING_TYPE avr_c_mode_for_floating_type
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 \f
diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h
index 56211fa9cd0..4977e15eeed 100644
--- a/gcc/config/avr/avr.h
+++ b/gcc/config/avr/avr.h
@@ -143,9 +143,6 @@ FIXME: DRIVER_SELF_SPECS has changed.
 #define SHORT_TYPE_SIZE (INT_TYPE_SIZE == 8 ? INT_TYPE_SIZE : 16)
 #define LONG_TYPE_SIZE (INT_TYPE_SIZE == 8 ? 16 : 32)
 #define LONG_LONG_TYPE_SIZE (INT_TYPE_SIZE == 8 ? 32 : 64)
-#define FLOAT_TYPE_SIZE 32
-#define DOUBLE_TYPE_SIZE (avr_double)
-#define LONG_DOUBLE_TYPE_SIZE (avr_long_double)
 
 #define LONG_LONG_ACCUM_TYPE_SIZE 64
 
diff --git a/gcc/config/bpf/bpf.h b/gcc/config/bpf/bpf.h
index e163fbf688d..2298e5b05af 100644
--- a/gcc/config/bpf/bpf.h
+++ b/gcc/config/bpf/bpf.h
@@ -90,9 +90,6 @@
 #define LONG_TYPE_SIZE        64
 #define LONG_LONG_TYPE_SIZE   64
 #define CHAR_TYPE_SIZE         8
-#define FLOAT_TYPE_SIZE       32
-#define DOUBLE_TYPE_SIZE      64
-#define LONG_DOUBLE_TYPE_SIZE 64
 
 #define INTPTR_TYPE	"long int"
 #define UINTPTR_TYPE	"long unsigned int"
diff --git a/gcc/config/darwin.cc b/gcc/config/darwin.cc
index 63b8c509405..9129378be37 100644
--- a/gcc/config/darwin.cc
+++ b/gcc/config/darwin.cc
@@ -3620,7 +3620,7 @@ darwin_patch_builtin (enum built_in_function fncode)
 void
 darwin_patch_builtins (void)
 {
-  if (LONG_DOUBLE_TYPE_SIZE != 128)
+  if (TYPE_PRECISION (long_double_type_node) != 128)
     return;
 
 #define PATCH_BUILTIN(fncode) darwin_patch_builtin (fncode);
diff --git a/gcc/config/epiphany/epiphany.h b/gcc/config/epiphany/epiphany.h
index 1df9eeecd0e..aa4715bfe10 100644
--- a/gcc/config/epiphany/epiphany.h
+++ b/gcc/config/epiphany/epiphany.h
@@ -188,9 +188,6 @@ along with GCC; see the file COPYING3.  If not see
 #define INT_TYPE_SIZE		32
 #define LONG_TYPE_SIZE		32
 #define LONG_LONG_TYPE_SIZE	64
-#define FLOAT_TYPE_SIZE		32
-#define DOUBLE_TYPE_SIZE	64
-#define LONG_DOUBLE_TYPE_SIZE	64
 
 /* Define this as 1 if `char' should by default be signed; else as 0.  */
 #define DEFAULT_SIGNED_CHAR 0
diff --git a/gcc/config/fr30/fr30.h b/gcc/config/fr30/fr30.h
index 2a2674ca29e..19020fbbd36 100644
--- a/gcc/config/fr30/fr30.h
+++ b/gcc/config/fr30/fr30.h
@@ -99,9 +99,6 @@ along with GCC; see the file COPYING3.  If not see
 #define INT_TYPE_SIZE 		32
 #define LONG_TYPE_SIZE 		32
 #define LONG_LONG_TYPE_SIZE 	64
-#define FLOAT_TYPE_SIZE 	32
-#define DOUBLE_TYPE_SIZE 	64
-#define LONG_DOUBLE_TYPE_SIZE 	64
 
 #define DEFAULT_SIGNED_CHAR 1
 
diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h
index 60225ee8230..b16103afff5 100644
--- a/gcc/config/frv/frv.h
+++ b/gcc/config/frv/frv.h
@@ -366,9 +366,6 @@
 #define INT_TYPE_SIZE         32
 #define LONG_TYPE_SIZE        32
 #define LONG_LONG_TYPE_SIZE   64
-#define FLOAT_TYPE_SIZE       32
-#define DOUBLE_TYPE_SIZE      64
-#define LONG_DOUBLE_TYPE_SIZE 64
 
 /* An expression whose value is 1 or 0, according to whether the type `char'
    should be signed or unsigned by default.  The user can always override this
diff --git a/gcc/config/ft32/ft32.h b/gcc/config/ft32/ft32.h
index 6d892a5ab8e..1803d5b6be0 100644
--- a/gcc/config/ft32/ft32.h
+++ b/gcc/config/ft32/ft32.h
@@ -53,10 +53,6 @@
 #define LONG_TYPE_SIZE 32
 #define LONG_LONG_TYPE_SIZE 64
 
-#define FLOAT_TYPE_SIZE 32
-#define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE 64
-
 #define DEFAULT_SIGNED_CHAR 1
 
 #undef  SIZE_TYPE
diff --git a/gcc/config/gcn/gcn.h b/gcc/config/gcn/gcn.h
index afa615320ca..e3bfd29c17d 100644
--- a/gcc/config/gcn/gcn.h
+++ b/gcc/config/gcn/gcn.h
@@ -111,9 +111,6 @@
 #define INT_TYPE_SIZE		  32
 #define LONG_TYPE_SIZE		  64
 #define LONG_LONG_TYPE_SIZE	  64
-#define FLOAT_TYPE_SIZE		  32
-#define DOUBLE_TYPE_SIZE	  64
-#define LONG_DOUBLE_TYPE_SIZE	  64
 #define DEFAULT_SIGNED_CHAR	  1
 #define PCC_BITFIELD_TYPE_MATTERS 1
 
diff --git a/gcc/config/h8300/h8300.cc b/gcc/config/h8300/h8300.cc
index 9ac6d52f9d6..9c1d4ccd049 100644
--- a/gcc/config/h8300/h8300.cc
+++ b/gcc/config/h8300/h8300.cc
@@ -5601,6 +5601,18 @@ h8300_ok_for_sibcall_p (tree fndecl, tree)
   return 1;
 }
 
+/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return SFmode or DFmode
+   for TI_{LONG_,}DOUBLE_TYPE which is for {long,} double type, go with
+   the default one for the others.  */
+
+static machine_mode
+h8300_c_mode_for_floating_type (enum tree_index ti)
+{
+  if (ti == TI_DOUBLE_TYPE || ti == TI_LONG_DOUBLE_TYPE)
+    return DOUBLE_TYPE_SIZE == 32 ? SFmode : DFmode;
+  return default_mode_for_floating_type (ti);
+}
+
 /* Return TRUE if OP is a PRE_INC or PRE_DEC
    instruction using REG, FALSE otherwise.  */
 
@@ -5721,4 +5733,7 @@ pre_incdec_with_reg (rtx op, unsigned int reg)
 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
 #define TARGET_FUNCTION_OK_FOR_SIBCALL h8300_ok_for_sibcall_p
 
+#undef TARGET_C_MODE_FOR_FLOATING_TYPE
+#define TARGET_C_MODE_FOR_FLOATING_TYPE h8300_c_mode_for_floating_type
+
 struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index b4838b7939e..c6b74ac59d3 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -25800,6 +25800,19 @@ ix86_bitint_type_info (int n, struct bitint_info *info)
   return true;
 }
 
+/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return DFmode, TFmode
+   or XFmode for TI_LONG_DOUBLE_TYPE which is for long double type,
+   based on long double bits, go with the default one for the others.  */
+
+static machine_mode
+ix86_c_mode_for_floating_type (enum tree_index ti)
+{
+  if (ti == TI_LONG_DOUBLE_TYPE)
+    return (TARGET_LONG_DOUBLE_64 ? DFmode
+				  : (TARGET_LONG_DOUBLE_128 ? TFmode : XFmode));
+  return default_mode_for_floating_type (ti);
+}
+
 /* Returns modified FUNCTION_TYPE for cdtor callabi.  */
 tree
 ix86_cxx_adjust_cdtor_callabi_fntype (tree fntype)
@@ -26425,6 +26438,8 @@ static const scoped_attribute_specs *const ix86_attribute_table[] =
 #define TARGET_C_EXCESS_PRECISION ix86_get_excess_precision
 #undef TARGET_C_BITINT_TYPE_INFO
 #define TARGET_C_BITINT_TYPE_INFO ix86_bitint_type_info
+#undef TARGET_C_MODE_FOR_FLOATING_TYPE
+#define TARGET_C_MODE_FOR_FLOATING_TYPE ix86_c_mode_for_floating_type
 #undef TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE
 #define TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE ix86_cxx_adjust_cdtor_callabi_fntype
 #undef TARGET_PROMOTE_PROTOTYPES
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 529edff93a4..220d808f2c0 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -677,10 +677,6 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
 #define LONG_TYPE_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD)
 #define POINTER_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD)
 #define LONG_LONG_TYPE_SIZE 64
-#define FLOAT_TYPE_SIZE 32
-#define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE \
-  (TARGET_LONG_DOUBLE_64 ? 64 : (TARGET_LONG_DOUBLE_128 ? 128 : 80))
 
 #define WIDEST_HARDWARE_FP_SIZE 80
 
diff --git a/gcc/config/ia64/ia64.cc b/gcc/config/ia64/ia64.cc
index ac3d56073ac..cd6ed895211 100644
--- a/gcc/config/ia64/ia64.cc
+++ b/gcc/config/ia64/ia64.cc
@@ -321,6 +321,7 @@ static const char *ia64_invalid_conversion (const_tree, const_tree);
 static const char *ia64_invalid_unary_op (int, const_tree);
 static const char *ia64_invalid_binary_op (int, const_tree, const_tree);
 static machine_mode ia64_c_mode_for_suffix (char);
+static machine_mode ia64_c_mode_for_floating_type (enum tree_index);
 static void ia64_trampoline_init (rtx, tree, rtx);
 static void ia64_override_options_after_change (void);
 static bool ia64_member_type_forces_blk (const_tree, machine_mode);
@@ -637,6 +638,9 @@ static const scoped_attribute_specs *const ia64_attribute_table[] =
 #undef TARGET_C_MODE_FOR_SUFFIX
 #define TARGET_C_MODE_FOR_SUFFIX ia64_c_mode_for_suffix
 
+#undef TARGET_C_MODE_FOR_FLOATING_TYPE
+#define TARGET_C_MODE_FOR_FLOATING_TYPE ia64_c_mode_for_floating_type
+
 #undef TARGET_CAN_ELIMINATE
 #define TARGET_CAN_ELIMINATE ia64_can_eliminate
 
@@ -11329,6 +11333,20 @@ ia64_c_mode_for_suffix (char suffix)
   return VOIDmode;
 }
 
+/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return DFmode, XFmode
+   or TFmode for TI_LONG_DOUBLE_TYPE which is for long double type,
+   go with the default one for the others.  */
+
+static machine_mode
+ia64_c_mode_for_floating_type (enum tree_index ti)
+{
+  /* long double is XFmode normally, and TFmode for HPUX.  It should be
+     TFmode for VMS as well but we only support up to DFmode now.  */
+  if (ti == TI_LONG_DOUBLE_TYPE)
+    return TARGET_HPUX ? TFmode : (TARGET_ABI_OPEN_VMS ? DFmode : XFmode);
+  return default_mode_for_floating_type (ti);
+}
+
 static GTY(()) rtx ia64_dconst_0_5_rtx;
 
 rtx
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index b7f9d654f90..763b1c3ed48 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -236,18 +236,6 @@ while (0)
 
 #define LONG_LONG_TYPE_SIZE 64
 
-#define FLOAT_TYPE_SIZE 32
-
-#define DOUBLE_TYPE_SIZE 64
-
-/* long double is XFmode normally, and TFmode for HPUX.  It should be
-   TFmode for VMS as well but we only support up to DFmode now.  */
-#define LONG_DOUBLE_TYPE_SIZE \
-  (TARGET_HPUX ? 128 \
-   : TARGET_ABI_OPEN_VMS ? 64 \
-   : 80)
-
-
 #define DEFAULT_SIGNED_CHAR 1
 
 /* A C expression for a string describing the name of the data type to use for
diff --git a/gcc/config/iq2000/iq2000.h b/gcc/config/iq2000/iq2000.h
index 88e87c6f603..c3562be0fb9 100644
--- a/gcc/config/iq2000/iq2000.h
+++ b/gcc/config/iq2000/iq2000.h
@@ -112,9 +112,6 @@
 #define LONG_TYPE_SIZE 		32
 #define LONG_LONG_TYPE_SIZE 	64
 #define CHAR_TYPE_SIZE		BITS_PER_UNIT
-#define FLOAT_TYPE_SIZE 	32
-#define DOUBLE_TYPE_SIZE 	64
-#define LONG_DOUBLE_TYPE_SIZE	64
 #define DEFAULT_SIGNED_CHAR	1
 
 #undef  SIZE_TYPE
diff --git a/gcc/config/lm32/lm32.h b/gcc/config/lm32/lm32.h
index 1d2c8adadfe..e761e14dcc5 100644
--- a/gcc/config/lm32/lm32.h
+++ b/gcc/config/lm32/lm32.h
@@ -122,10 +122,6 @@ do {                                                    \
 #define LONG_TYPE_SIZE		    32
 #define LONG_LONG_TYPE_SIZE	    64
 
-#define FLOAT_TYPE_SIZE		    32
-#define DOUBLE_TYPE_SIZE	    64
-#define LONG_DOUBLE_TYPE_SIZE       64
-
 #define DEFAULT_SIGNED_CHAR         0
 
 #define SIZE_TYPE "unsigned int"
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index e7835ae34ae..e4a51303d22 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -10946,6 +10946,18 @@ loongarch_builtin_support_vector_misalignment (machine_mode mode,
 						      is_packed);
 }
 
+/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return TFmode or DFmode
+   for TI_LONG_DOUBLE_TYPE which is for long double type, go with the
+   default one for the others.  */
+
+static machine_mode
+loongarch_c_mode_for_floating_type (enum tree_index ti)
+{
+  if (ti == TI_LONG_DOUBLE_TYPE)
+    return TARGET_64BIT ? TFmode : DFmode;
+  return default_mode_for_floating_type (ti);
+}
+
 static bool
 use_rsqrt_p (void)
 {
@@ -11256,6 +11268,9 @@ loongarch_asm_code_end (void)
 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
   loongarch_builtin_support_vector_misalignment
 
+#undef TARGET_C_MODE_FOR_FLOATING_TYPE
+#define TARGET_C_MODE_FOR_FLOATING_TYPE loongarch_c_mode_for_floating_type
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-loongarch.h"
diff --git a/gcc/config/m32c/m32c.h b/gcc/config/m32c/m32c.h
index 247b4358cf9..a956c507d8d 100644
--- a/gcc/config/m32c/m32c.h
+++ b/gcc/config/m32c/m32c.h
@@ -180,10 +180,6 @@ machine_function;
 #define LONG_TYPE_SIZE 32
 #define LONG_LONG_TYPE_SIZE 64
 
-#define FLOAT_TYPE_SIZE 32
-#define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE 64
-
 #define DEFAULT_SIGNED_CHAR 1
 
 #undef PTRDIFF_TYPE
diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h
index 4a400d1654f..7be8dfd7916 100644
--- a/gcc/config/m32r/m32r.h
+++ b/gcc/config/m32r/m32r.h
@@ -279,9 +279,6 @@
 #define INT_TYPE_SIZE		32
 #define LONG_TYPE_SIZE		32
 #define LONG_LONG_TYPE_SIZE	64
-#define FLOAT_TYPE_SIZE		32
-#define DOUBLE_TYPE_SIZE	64
-#define LONG_DOUBLE_TYPE_SIZE	64
 
 /* Define this as 1 if `char' should by default be signed; else as 0.  */
 #define DEFAULT_SIGNED_CHAR 1
diff --git a/gcc/config/m68k/m68k.cc b/gcc/config/m68k/m68k.cc
index b1c9238949f..e6488215594 100644
--- a/gcc/config/m68k/m68k.cc
+++ b/gcc/config/m68k/m68k.cc
@@ -198,6 +198,7 @@ static machine_mode m68k_promote_function_mode (const_tree, machine_mode,
 						int *, const_tree, int);
 static void m68k_asm_final_postscan_insn (FILE *, rtx_insn *insn, rtx [], int);
 static HARD_REG_SET m68k_zero_call_used_regs (HARD_REG_SET);
+static machine_mode m68k_c_mode_for_floating_type (enum tree_index);
 \f
 /* Initialize the GCC target structure.  */
 
@@ -365,6 +366,9 @@ static HARD_REG_SET m68k_zero_call_used_regs (HARD_REG_SET);
 #undef TARGET_ZERO_CALL_USED_REGS
 #define TARGET_ZERO_CALL_USED_REGS m68k_zero_call_used_regs
 
+#undef TARGET_C_MODE_FOR_FLOATING_TYPE
+#define TARGET_C_MODE_FOR_FLOATING_TYPE m68k_c_mode_for_floating_type
+
 TARGET_GNU_ATTRIBUTES (m68k_attribute_table,
 {
   /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
@@ -7212,4 +7216,16 @@ m68k_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
   return need_zeroed_hardregs;
 }
 
+/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return XFmode or DFmode
+   for TI_LONG_DOUBLE_TYPE which is for long double type, go with the
+   default one for the others.  */
+
+static machine_mode
+m68k_c_mode_for_floating_type (enum tree_index ti)
+{
+  if (ti == TI_LONG_DOUBLE_TYPE)
+    return LONG_DOUBLE_TYPE_SIZE == 64 ? DFmode : XFmode;
+  return default_mode_for_floating_type (ti);
+}
+
 #include "gt-m68k.h"
diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
index c88a87c12e2..5d28abf9741 100644
--- a/gcc/config/microblaze/microblaze.h
+++ b/gcc/config/microblaze/microblaze.h
@@ -216,9 +216,6 @@ extern enum pipeline_type microblaze_pipe;
 #define SHORT_TYPE_SIZE         16
 #define LONG_TYPE_SIZE          32
 #define LONG_LONG_TYPE_SIZE     64
-#define FLOAT_TYPE_SIZE         32
-#define DOUBLE_TYPE_SIZE        64
-#define LONG_DOUBLE_TYPE_SIZE   64
 #define POINTER_SIZE            32
 #define PARM_BOUNDARY           32
 #define FUNCTION_BOUNDARY       32
diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index ce764a5cb35..7447ae0fcda 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -22982,6 +22982,18 @@ mips_asm_file_end (void)
     file_end_indicate_exec_stack ();
 }
 
+/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return TFmode or DFmode
+   for TI_LONG_DOUBLE_TYPE which is for long double type, go with the
+   default one for the others.  */
+
+static machine_mode
+mips_c_mode_for_floating_type (enum tree_index ti)
+{
+  if (ti == TI_LONG_DOUBLE_TYPE)
+    return LONG_DOUBLE_TYPE_SIZE == 64 ? DFmode : TFmode;
+  return default_mode_for_floating_type (ti);
+}
+
 void
 mips_bit_clear_info (enum machine_mode mode, unsigned HOST_WIDE_INT m,
 		      int *start_pos, int *size)
@@ -23352,6 +23364,8 @@ mips_bit_clear_p (enum machine_mode mode, unsigned HOST_WIDE_INT m)
 #undef TARGET_ASM_FILE_END
 #define TARGET_ASM_FILE_END mips_asm_file_end
 
+#undef TARGET_C_MODE_FOR_FLOATING_TYPE
+#define TARGET_C_MODE_FOR_FLOATING_TYPE mips_c_mode_for_floating_type
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
diff --git a/gcc/config/mmix/mmix.h b/gcc/config/mmix/mmix.h
index c3c5a2a69c9..e20bca1d363 100644
--- a/gcc/config/mmix/mmix.h
+++ b/gcc/config/mmix/mmix.h
@@ -195,10 +195,6 @@ struct GTY(()) machine_function
 #define SHORT_TYPE_SIZE 16
 #define LONG_LONG_TYPE_SIZE 64
 
-#define FLOAT_TYPE_SIZE 32
-#define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE 64
-
 #define DEFAULT_SIGNED_CHAR 1
 
 
diff --git a/gcc/config/moxie/moxie.h b/gcc/config/moxie/moxie.h
index 066c2566d84..4857c92890f 100644
--- a/gcc/config/moxie/moxie.h
+++ b/gcc/config/moxie/moxie.h
@@ -55,10 +55,6 @@
 #define LONG_TYPE_SIZE 32
 #define LONG_LONG_TYPE_SIZE 64
 
-#define FLOAT_TYPE_SIZE 32
-#define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE 64
-
 #define DEFAULT_SIGNED_CHAR 0
 
 #undef  SIZE_TYPE
diff --git a/gcc/config/msp430/msp430.h b/gcc/config/msp430/msp430.h
index 5c856ee6997..f20309c65ac 100644
--- a/gcc/config/msp430/msp430.h
+++ b/gcc/config/msp430/msp430.h
@@ -178,10 +178,6 @@ extern const char *msp430_get_linker_devices_include_path (int, const char **);
 #define LONG_TYPE_SIZE			32
 #define LONG_LONG_TYPE_SIZE		64
 
-#define FLOAT_TYPE_SIZE 		32
-#define DOUBLE_TYPE_SIZE 		64
-#define LONG_DOUBLE_TYPE_SIZE		64 /*DOUBLE_TYPE_SIZE*/
-
 #define DEFAULT_SIGNED_CHAR		0
 
 #define STRICT_ALIGNMENT 		1
diff --git a/gcc/config/nds32/nds32.h b/gcc/config/nds32/nds32.h
index 03cf7a9aa56..4c02302c785 100644
--- a/gcc/config/nds32/nds32.h
+++ b/gcc/config/nds32/nds32.h
@@ -1061,10 +1061,6 @@ enum nds32_builtins
 #define LONG_TYPE_SIZE          32
 #define LONG_LONG_TYPE_SIZE     64
 
-#define FLOAT_TYPE_SIZE         32
-#define DOUBLE_TYPE_SIZE        64
-#define LONG_DOUBLE_TYPE_SIZE   64
-
 #define DEFAULT_SIGNED_CHAR 1
 
 #define SIZE_TYPE "long unsigned int"
diff --git a/gcc/config/nios2/nios2.h b/gcc/config/nios2/nios2.h
index 767f56e95b1..bad726713eb 100644
--- a/gcc/config/nios2/nios2.h
+++ b/gcc/config/nios2/nios2.h
@@ -100,9 +100,6 @@
 #define SHORT_TYPE_SIZE 16
 #define LONG_TYPE_SIZE 32
 #define LONG_LONG_TYPE_SIZE 64
-#define FLOAT_TYPE_SIZE 32
-#define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE DOUBLE_TYPE_SIZE
 
 #undef SIZE_TYPE
 #define SIZE_TYPE "unsigned int"
diff --git a/gcc/config/nvptx/nvptx.h b/gcc/config/nvptx/nvptx.h
index e282aad1b73..f6077c09e9b 100644
--- a/gcc/config/nvptx/nvptx.h
+++ b/gcc/config/nvptx/nvptx.h
@@ -75,9 +75,6 @@
 #define INT_TYPE_SIZE 32
 #define LONG_TYPE_SIZE (TARGET_ABI64 ? 64 : 32)
 #define LONG_LONG_TYPE_SIZE 64
-#define FLOAT_TYPE_SIZE 32
-#define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE 64
 #define TARGET_SUPPORTS_WIDE_INT 1
 
 #undef SIZE_TYPE
diff --git a/gcc/config/or1k/or1k.h b/gcc/config/or1k/or1k.h
index 0ff73df33e7..a55509f9f32 100644
--- a/gcc/config/or1k/or1k.h
+++ b/gcc/config/or1k/or1k.h
@@ -67,9 +67,6 @@
 #define SHORT_TYPE_SIZE 16
 #define LONG_TYPE_SIZE 32
 #define LONG_LONG_TYPE_SIZE 64
-#define FLOAT_TYPE_SIZE 32
-#define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE 64
 #define WCHAR_TYPE_SIZE 32
 
 #undef SIZE_TYPE
diff --git a/gcc/config/pa/pa-hpux.h b/gcc/config/pa/pa-hpux.h
index a7421d68ca0..b87302abdc0 100644
--- a/gcc/config/pa/pa-hpux.h
+++ b/gcc/config/pa/pa-hpux.h
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.  If not see
 #define SIZE_TYPE "unsigned int"
 #define PTRDIFF_TYPE "int"
 
+#undef LONG_DOUBLE_TYPE_SIZE
 #define LONG_DOUBLE_TYPE_SIZE 128
 #define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) ((MODE) == TFmode)
 
diff --git a/gcc/config/pa/pa.cc b/gcc/config/pa/pa.cc
index a7af6b8c121..cd0a2116121 100644
--- a/gcc/config/pa/pa.cc
+++ b/gcc/config/pa/pa.cc
@@ -194,6 +194,7 @@ static rtx pa_internal_arg_pointer (void);
 static bool pa_can_eliminate (const int, const int);
 static void pa_conditional_register_usage (void);
 static machine_mode pa_c_mode_for_suffix (char);
+static machine_mode pa_c_mode_for_floating_type (enum tree_index);
 static section *pa_function_section (tree, enum node_frequency, bool, bool);
 static bool pa_cannot_force_const_mem (machine_mode, rtx);
 static bool pa_legitimate_constant_p (machine_mode, rtx);
@@ -398,6 +399,8 @@ static size_t n_deferred_plabels = 0;
 #define TARGET_CONDITIONAL_REGISTER_USAGE pa_conditional_register_usage
 #undef TARGET_C_MODE_FOR_SUFFIX
 #define TARGET_C_MODE_FOR_SUFFIX pa_c_mode_for_suffix
+#undef TARGET_C_MODE_FOR_FLOATING_TYPE
+#define TARGET_C_MODE_FOR_FLOATING_TYPE pa_c_mode_for_floating_type
 #undef TARGET_ASM_FUNCTION_SECTION
 #define TARGET_ASM_FUNCTION_SECTION pa_function_section
 
@@ -10808,6 +10811,18 @@ pa_c_mode_for_suffix (char suffix)
   return VOIDmode;
 }
 
+/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return TFmode or DFmode
+   for TI_LONG_DOUBLE_TYPE which is for long double type, go with the
+   default one for the others.  */
+
+static machine_mode
+pa_c_mode_for_floating_type (enum tree_index ti)
+{
+  if (ti == TI_LONG_DOUBLE_TYPE)
+    return LONG_DOUBLE_TYPE_SIZE == 64 ? DFmode : TFmode;
+  return default_mode_for_floating_type (ti);
+}
+
 /* Target hook for function_section.  */
 
 static section *
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 127a0d1966d..99844dad115 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -1306,3 +1306,8 @@ do {									     \
 /* An integer expression for the size in bits of the largest integer machine
    mode that should actually be used.  We allow pairs of registers.  */
 #define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TARGET_64BIT ? TImode : DImode)
+
+/* Define these macros as defaults.h doesn't define them any more.  */
+#define FLOAT_TYPE_SIZE BITS_PER_WORD
+#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
+#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
diff --git a/gcc/config/pdp11/pdp11.h b/gcc/config/pdp11/pdp11.h
index 2446fea0b58..6c8e045bc57 100644
--- a/gcc/config/pdp11/pdp11.h
+++ b/gcc/config/pdp11/pdp11.h
@@ -71,17 +71,6 @@ along with GCC; see the file COPYING3.  If not see
 #define LONG_TYPE_SIZE		32
 #define LONG_LONG_TYPE_SIZE	64     
 
-/* In earlier versions, FLOAT_TYPE_SIZE was selectable as 32 or 64,
-   but that conflicts with Fortran language rules.  Since there is no
-   obvious reason why we should have that feature -- other targets
-   generally don't have float and double the same size -- I've removed
-   it.  Note that it continues to be true (for now) that arithmetic is
-   always done with 64-bit values, i.e., the FPU is always in "double"
-   mode.  */
-#define FLOAT_TYPE_SIZE		32
-#define DOUBLE_TYPE_SIZE	64
-#define LONG_DOUBLE_TYPE_SIZE	64
-
 /* machine types from ansi */
 #define SIZE_TYPE "short unsigned int" 	/* definition of size_t */
 #define WCHAR_TYPE "short int" 		/* or long int???? */
diff --git a/gcc/config/pru/pru.h b/gcc/config/pru/pru.h
index 28aeb603178..7aee2861871 100644
--- a/gcc/config/pru/pru.h
+++ b/gcc/config/pru/pru.h
@@ -107,9 +107,6 @@
 #define SHORT_TYPE_SIZE 16
 #define LONG_TYPE_SIZE 32
 #define LONG_LONG_TYPE_SIZE 64
-#define FLOAT_TYPE_SIZE 32
-#define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE DOUBLE_TYPE_SIZE
 
 #undef SIZE_TYPE
 #define SIZE_TYPE "unsigned int"
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 4067505270e..efdc26317bd 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -11281,6 +11281,18 @@ riscv_get_raw_result_mode (int regno)
   return default_get_reg_raw_mode (regno);
 }
 
+/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return TFmode for
+   TI_LONG_DOUBLE_TYPE which is for long double type, go with the
+   default one for the others.  */
+
+static machine_mode
+riscv_c_mode_for_floating_type (enum tree_index ti)
+{
+  if (ti == TI_LONG_DOUBLE_TYPE)
+    return TFmode;
+  return default_mode_for_floating_type (ti);
+}
+
 /* Initialize the GCC target structure.  */
 #undef TARGET_ASM_ALIGNED_HI_OP
 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
@@ -11636,6 +11648,9 @@ riscv_get_raw_result_mode (int regno)
 #undef TARGET_GET_RAW_RESULT_MODE
 #define TARGET_GET_RAW_RESULT_MODE riscv_get_raw_result_mode
 
+#undef TARGET_C_MODE_FOR_FLOATING_TYPE
+#define TARGET_C_MODE_FOR_FLOATING_TYPE riscv_c_mode_for_floating_type
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-riscv.h"
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 0d27c0d378d..31082dbd600 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -188,10 +188,6 @@ ASM_MISA_SPEC
 #define POINTER_SIZE (riscv_abi >= ABI_LP64 ? 64 : 32)
 #define LONG_TYPE_SIZE POINTER_SIZE
 
-#define FLOAT_TYPE_SIZE 32
-#define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE 128
-
 /* Allocation boundary (in *bits*) for storing arguments in argument list.  */
 #define PARM_BOUNDARY BITS_PER_WORD
 
diff --git a/gcc/config/rl78/rl78.cc b/gcc/config/rl78/rl78.cc
index e5345bfa9dd..ccb1c4f3867 100644
--- a/gcc/config/rl78/rl78.cc
+++ b/gcc/config/rl78/rl78.cc
@@ -4971,6 +4971,21 @@ rl78_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t rclass)
   return rclass;
 }
 
+#undef TARGET_C_MODE_FOR_FLOATING_TYPE
+#define TARGET_C_MODE_FOR_FLOATING_TYPE rl78_c_mode_for_floating_type
+
+/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return SFmode for
+   TI_DOUBLE_TYPE which is for double type, go with the default
+   one for the others.  */
+
+static machine_mode
+rl78_c_mode_for_floating_type (enum tree_index ti)
+{
+  if (ti == TI_DOUBLE_TYPE)
+    return SFmode;
+  return default_mode_for_floating_type (ti);
+}
+
 \f
 /* The strub runtime uses asms, and physical register allocation won't
    deal with them, so disable it.  */
diff --git a/gcc/config/rl78/rl78.h b/gcc/config/rl78/rl78.h
index cfff98df6bc..a960aee3931 100644
--- a/gcc/config/rl78/rl78.h
+++ b/gcc/config/rl78/rl78.h
@@ -113,10 +113,6 @@
 #define LONG_TYPE_SIZE			32
 #define LONG_LONG_TYPE_SIZE		64
 
-#define FLOAT_TYPE_SIZE 		32
-#define DOUBLE_TYPE_SIZE 		32 /*64*/
-#define LONG_DOUBLE_TYPE_SIZE		64 /*DOUBLE_TYPE_SIZE*/
-
 #define DEFAULT_SIGNED_CHAR		0
 
 #define STRICT_ALIGNMENT 		1
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index e713a1e1d57..2c262edd327 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -1707,6 +1707,9 @@ static const scoped_attribute_specs *const rs6000_attribute_table[] =
 #undef TARGET_C_MODE_FOR_SUFFIX
 #define TARGET_C_MODE_FOR_SUFFIX rs6000_c_mode_for_suffix
 
+#undef TARGET_C_MODE_FOR_FLOATING_TYPE
+#define TARGET_C_MODE_FOR_FLOATING_TYPE rs6000_c_mode_for_floating_type
+
 #undef TARGET_INVALID_BINARY_OP
 #define TARGET_INVALID_BINARY_OP rs6000_invalid_binary_op
 
@@ -24364,6 +24367,19 @@ rs6000_c_mode_for_suffix (char suffix)
   return VOIDmode;
 }
 
+/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return TFmode for
+   TI_LONG_DOUBLE_TYPE which is for long double type, go with the default
+   one for the others.  */
+
+static machine_mode
+rs6000_c_mode_for_floating_type (enum tree_index ti)
+{
+  if (ti == TI_LONG_DOUBLE_TYPE)
+    return rs6000_long_double_type_size == FLOAT_PRECISION_TFmode ? TFmode
+								  : DFmode;
+  return default_mode_for_floating_type (ti);
+}
+
 /* Target hook for invalid_arg_for_unprototyped_fn. */
 static const char *
 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 2cde2e329b0..9211f91740a 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -693,20 +693,6 @@ extern unsigned char rs6000_recip_bits[];
    words.  */
 #define LONG_LONG_TYPE_SIZE 64
 
-/* A C expression for the size in bits of the type `float' on the
-   target machine.  If you don't define this, the default is one
-   word.  */
-#define FLOAT_TYPE_SIZE 32
-
-/* A C expression for the size in bits of the type `double' on the
-   target machine.  If you don't define this, the default is two
-   words.  */
-#define DOUBLE_TYPE_SIZE 64
-
-/* A C expression for the size in bits of the type `long double' on the target
-   machine.  If you don't define this, the default is two words.  */
-#define LONG_DOUBLE_TYPE_SIZE rs6000_long_double_type_size
-
 /* Work around rs6000_long_double_type_size dependency in ada/targtyps.cc.  */
 #define WIDEST_HARDWARE_FP_SIZE 64
 
diff --git a/gcc/config/rx/rx.cc b/gcc/config/rx/rx.cc
index 9bf9d87fed1..8048cc98708 100644
--- a/gcc/config/rx/rx.cc
+++ b/gcc/config/rx/rx.cc
@@ -3648,6 +3648,18 @@ rx_modes_tieable_p (machine_mode mode1, machine_mode mode2)
 	  == (GET_MODE_CLASS (mode2) == MODE_FLOAT
 	      || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT));
 }
+
+/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return SFmode or DFmode
+   for TI_{LONG_,}DOUBLE_TYPE which is for {long,} double type, go with
+   the default one for the others.  */
+
+static machine_mode
+rx_c_mode_for_floating_type (enum tree_index ti)
+{
+  if (ti == TI_DOUBLE_TYPE || ti == TI_LONG_DOUBLE_TYPE)
+    return TARGET_64BIT_DOUBLES ? DFmode : SFmode;
+  return default_mode_for_floating_type (ti);
+}
 \f
 #undef  TARGET_NARROW_VOLATILE_BITFIELD
 #define TARGET_NARROW_VOLATILE_BITFIELD		rx_narrow_volatile_bitfield
@@ -3807,6 +3819,9 @@ rx_modes_tieable_p (machine_mode mode1, machine_mode mode2)
 #undef  TARGET_HAVE_SPECULATION_SAFE_VALUE
 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
 
+#undef TARGET_C_MODE_FOR_FLOATING_TYPE
+#define TARGET_C_MODE_FOR_FLOATING_TYPE rx_c_mode_for_floating_type
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-rx.h"
diff --git a/gcc/config/rx/rx.h b/gcc/config/rx/rx.h
index ff445df49a3..15d6d2503e7 100644
--- a/gcc/config/rx/rx.h
+++ b/gcc/config/rx/rx.h
@@ -132,10 +132,6 @@
 #define LONG_TYPE_SIZE			32
 #define LONG_LONG_TYPE_SIZE		64
 
-#define FLOAT_TYPE_SIZE 		32
-#define DOUBLE_TYPE_SIZE 		(TARGET_64BIT_DOUBLES ? 64 : 32)
-#define LONG_DOUBLE_TYPE_SIZE		DOUBLE_TYPE_SIZE
-
 #define DEFAULT_SIGNED_CHAR		0
 
 /* RX load/store instructions can handle unaligned addresses.  */
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index 5968808fcb6..22a1cedc12e 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -18037,6 +18037,18 @@ s390_vectorize_vec_perm_const (machine_mode vmode, machine_mode op_mode,
   return vectorize_vec_perm_const_1 (d);
 }
 
+/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return TFmode or DFmode
+   for TI_LONG_DOUBLE_TYPE which is for long double type, go with the
+   default one for the others.  */
+
+static machine_mode
+s390_c_mode_for_floating_type (enum tree_index ti)
+{
+  if (ti == TI_LONG_DOUBLE_TYPE)
+    return TARGET_LONG_DOUBLE_128 ? TFmode : DFmode;
+  return default_mode_for_floating_type (ti);
+}
+
 /* Initialize GCC target structure.  */
 
 #undef  TARGET_ASM_ALIGNED_HI_OP
@@ -18350,6 +18362,9 @@ s390_vectorize_vec_perm_const (machine_mode vmode, machine_mode op_mode,
 #undef TARGET_VECTORIZE_VEC_PERM_CONST
 #define TARGET_VECTORIZE_VEC_PERM_CONST s390_vectorize_vec_perm_const
 
+#undef TARGET_C_MODE_FOR_FLOATING_TYPE
+#define TARGET_C_MODE_FOR_FLOATING_TYPE s390_c_mode_for_floating_type
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-s390.h"
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index 0e6666a8802..4a4dde1a9ba 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -396,9 +396,6 @@ extern const char *s390_host_detect_local_cpu (int argc, const char **argv);
 #define INT_TYPE_SIZE 32
 #define LONG_TYPE_SIZE (TARGET_64BIT ? 64 : 32)
 #define LONG_LONG_TYPE_SIZE 64
-#define FLOAT_TYPE_SIZE 32
-#define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
 
 /* Work around target_flags dependency in ada/targtyps.cc.  */
 #define WIDEST_HARDWARE_FP_SIZE 64
diff --git a/gcc/config/sh/sh.cc b/gcc/config/sh/sh.cc
index ef3c2e6791d..bc017420381 100644
--- a/gcc/config/sh/sh.cc
+++ b/gcc/config/sh/sh.cc
@@ -328,6 +328,7 @@ static unsigned int sh_hard_regno_nregs (unsigned int, machine_mode);
 static bool sh_hard_regno_mode_ok (unsigned int, machine_mode);
 static bool sh_modes_tieable_p (machine_mode, machine_mode);
 static bool sh_can_change_mode_class (machine_mode, machine_mode, reg_class_t);
+static machine_mode sh_c_mode_for_floating_type (enum tree_index);
 \f
 TARGET_GNU_ATTRIBUTES (sh_attribute_table,
 {
@@ -664,6 +665,9 @@ TARGET_GNU_ATTRIBUTES (sh_attribute_table,
 #undef  TARGET_HAVE_SPECULATION_SAFE_VALUE
 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
 
+#undef TARGET_C_MODE_FOR_FLOATING_TYPE
+#define TARGET_C_MODE_FOR_FLOATING_TYPE sh_c_mode_for_floating_type
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 
@@ -10674,6 +10678,20 @@ sh_can_change_mode_class (machine_mode from, machine_mode to,
   return true;
 }
 
+/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return SFmode or DFmode
+   for TI_DOUBLE_TYPE which is for double type, go with the default one
+   for the others.  */
+
+static machine_mode
+sh_c_mode_for_floating_type (enum tree_index ti)
+{
+  /* Since the SH2e has only `float' support, it is desirable to make all
+     floating point types equivalent to `float'.  */
+  if (ti == TI_DOUBLE_TYPE)
+    return TARGET_FPU_SINGLE_ONLY ? SFmode : DFmode;
+  return default_mode_for_floating_type (ti);
+}
+
 /* Return true if registers in machine mode MODE will likely be
    allocated to registers in small register classes.  */
 bool
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 7d3a3f08338..53cad85d122 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -425,9 +425,6 @@ extern const sh_atomic_model& selected_atomic_model (void);
 /* Width in bits of a `long long'.  */
 #define LONG_LONG_TYPE_SIZE 64
 
-/* Width in bits of a `long double'.  */
-#define LONG_DOUBLE_TYPE_SIZE 64
-
 /* Width of a word, in units (bytes).  */
 #define UNITS_PER_WORD	(4)
 #define MIN_UNITS_PER_WORD 4
@@ -1433,13 +1430,6 @@ extern bool current_function_interrupt;
    Do not define this if the table should contain absolute addresses.  */
 #define CASE_VECTOR_PC_RELATIVE 1
 
-/* Define it here, so that it doesn't get bumped to 64-bits on SHmedia.  */
-#define FLOAT_TYPE_SIZE 32
-
-/* Since the SH2e has only `float' support, it is desirable to make all
-   floating point types equivalent to `float'.  */
-#define DOUBLE_TYPE_SIZE (TARGET_FPU_SINGLE_ONLY ? 32 : 64)
-
 /* 'char' is signed by default.  */
 #define DEFAULT_SIGNED_CHAR  1
 
diff --git a/gcc/config/sparc/sparc.cc b/gcc/config/sparc/sparc.cc
index 8a5f76c8885..c9df49bf0f6 100644
--- a/gcc/config/sparc/sparc.cc
+++ b/gcc/config/sparc/sparc.cc
@@ -718,6 +718,7 @@ static bool sparc_vectorize_vec_perm_const (machine_mode, machine_mode,
 					    const vec_perm_indices &);
 static bool sparc_can_follow_jump (const rtx_insn *, const rtx_insn *);
 static HARD_REG_SET sparc_zero_call_used_regs (HARD_REG_SET);
+static machine_mode sparc_c_mode_for_floating_type (enum tree_index);
 \f
 #ifdef SUBTARGET_ATTRIBUTE_TABLE
 /* Table of valid machine attributes.  */
@@ -971,6 +972,9 @@ char sparc_hard_reg_printed[8];
 #undef TARGET_ZERO_CALL_USED_REGS
 #define TARGET_ZERO_CALL_USED_REGS sparc_zero_call_used_regs
 
+#undef TARGET_C_MODE_FOR_FLOATING_TYPE
+#define TARGET_C_MODE_FOR_FLOATING_TYPE sparc_c_mode_for_floating_type
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 /* Return the memory reference contained in X if any, zero otherwise.  */
@@ -9824,14 +9828,6 @@ sparc_assemble_integer (rtx x, unsigned int size, int aligned_p)
 #define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2)
 #endif
 
-#ifndef FLOAT_TYPE_SIZE
-#define FLOAT_TYPE_SIZE BITS_PER_WORD
-#endif
-
-#ifndef DOUBLE_TYPE_SIZE
-#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
-#endif
-
 #ifndef LONG_DOUBLE_TYPE_SIZE
 #define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
 #endif
@@ -13984,4 +13980,16 @@ sparc_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
   return need_zeroed_hardregs;
 }
 
+/* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return TFmode or DFmode
+   for TI_LONG_DOUBLE_TYPE which is for long double type, go with the
+   default one for the others.  */
+
+static machine_mode
+sparc_c_mode_for_floating_type (enum tree_index ti)
+{
+  if (ti == TI_LONG_DOUBLE_TYPE)
+    return LONG_DOUBLE_TYPE_SIZE == 128 ? TFmode : DFmode;
+  return default_mode_for_floating_type (ti);
+}
+
 #include "gt-sparc.h"
diff --git a/gcc/config/stormy16/stormy16.h b/gcc/config/stormy16/stormy16.h
index 2503f234c6a..3d5e21d644d 100644
--- a/gcc/config/stormy16/stormy16.h
+++ b/gcc/config/stormy16/stormy16.h
@@ -101,12 +101,6 @@
 
 #define LONG_LONG_TYPE_SIZE 64
 
-#define FLOAT_TYPE_SIZE 32
-
-#define DOUBLE_TYPE_SIZE 64
-
-#define LONG_DOUBLE_TYPE_SIZE 64
-
 #define DEFAULT_SIGNED_CHAR 0
 
 #define SIZE_TYPE "unsigned int"
diff --git a/gcc/config/visium/visium.h b/gcc/config/visium/visium.h
index 69e25523e05..afeb68f84cc 100644
--- a/gcc/config/visium/visium.h
+++ b/gcc/config/visium/visium.h
@@ -330,33 +330,16 @@
    it is rounded up to one unit.) */
 #define CHAR_TYPE_SIZE  8
 
-/* `FLOAT_TYPE_SIZE'
-
-   A C expression for the size in bits of the type `float' on the
-   target machine.  If you don't define this, the default is one word. */
-#define FLOAT_TYPE_SIZE  32
-
-/* `DOUBLE_TYPE_SIZE'
-
-   A C expression for the size in bits of the type `double' on the
-   target machine.  If you don't define this, the default is two
-   words. */
-#define DOUBLE_TYPE_SIZE  64
-
-/* `LONG_DOUBLE_TYPE_SIZE'
-
-   A C expression for the size in bits of the type `long double' on
-   the target machine.  If you don't define this, the default is two
-   words. */
-#define LONG_DOUBLE_TYPE_SIZE   DOUBLE_TYPE_SIZE
-
 /* `WIDEST_HARDWARE_FP_SIZE'
 
    A C expression for the size in bits of the widest floating-point
    format supported by the hardware.  If you define this macro, you
-   must specify a value less than or equal to the value of
-   `LONG_DOUBLE_TYPE_SIZE'.  If you do not define this macro, the
-   value of `LONG_DOUBLE_TYPE_SIZE' is the default. */
+   must specify a value less than or equal to mode precision of the
+   mode used for C type long double (from hook
+   targetm.c.mode_for_floating_type with tree_index
+   TI_LONG_DOUBLE_TYPE).  If you do not define this macro, mode
+   precision of the mode used for C type long double is the
+   default.  */
 
 /* `DEFAULT_SIGNED_CHAR'
 
diff --git a/gcc/config/vms/vms.cc b/gcc/config/vms/vms.cc
index d468c79e559..2fcc673c8a9 100644
--- a/gcc/config/vms/vms.cc
+++ b/gcc/config/vms/vms.cc
@@ -141,6 +141,7 @@ vms_patch_builtins (void)
   if (builtin_decl_implicit_p (BUILT_IN_FWRITE_UNLOCKED))
     set_builtin_decl_implicit_p (BUILT_IN_FWRITE_UNLOCKED, false);
 
+  unsigned long_double_type_size = TYPE_PRECISION (long_double_type_node);
   /* Define aliases for names.  */
   for (i = 0; i < NBR_CRTL_NAMES; i++)
     {
@@ -179,7 +180,7 @@ vms_patch_builtins (void)
 	  vms_add_crtl_xlat (alt, nlen + 1, res, rlen);
 
 	  /* Long double version.  */
-	  res[rlen - 1] = (LONG_DOUBLE_TYPE_SIZE == 128 ? 'X' : 'T');
+	  res[rlen - 1] = (long_double_type_size == 128 ? 'X' : 'T');
 	  alt[nlen] = 'l';
 	  vms_add_crtl_xlat (alt, nlen + 1, res, rlen);
 
@@ -223,7 +224,7 @@ vms_patch_builtins (void)
       if (n->flags & VMS_CRTL_FLOAT64)
         res[rlen++] = 't';
 
-      if ((n->flags & VMS_CRTL_FLOAT128) && LONG_DOUBLE_TYPE_SIZE == 128)
+      if ((n->flags & VMS_CRTL_FLOAT128) && long_double_type_size == 128)
         res[rlen++] = 'x';
 
       memcpy (res + rlen, n->name, nlen);
diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h
index 9591b3d4b40..06f1e24f7b7 100644
--- a/gcc/config/xtensa/xtensa.h
+++ b/gcc/config/xtensa/xtensa.h
@@ -120,9 +120,6 @@ along with GCC; see the file COPYING3.  If not see
 #define SHORT_TYPE_SIZE 16
 #define LONG_TYPE_SIZE 32
 #define LONG_LONG_TYPE_SIZE 64
-#define FLOAT_TYPE_SIZE 32
-#define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE 64
 
 /* Allocation boundary (in *bits*) for storing pointers in memory.  */
 #define POINTER_BOUNDARY 32
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 1ac6f0abea3..00c1c58bd8c 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -100,6 +100,7 @@ struct gimple;
 typedef gimple *gimple_seq;
 struct gimple_stmt_iterator;
 class code_helper;
+enum tree_index : unsigned;
 
 /* Forward declare rtx_code, so that we can use it in target hooks without
    needing to pull in rtl.h.  */
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index 127b9d7ce7c..079731f68ab 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -163,7 +163,8 @@ Target::_init (const Param &)
   this->c.intsize = (INT_TYPE_SIZE / BITS_PER_UNIT);
   this->c.longsize = (LONG_TYPE_SIZE / BITS_PER_UNIT);
   this->c.long_longsize = (LONG_LONG_TYPE_SIZE / BITS_PER_UNIT);
-  this->c.long_doublesize = (LONG_DOUBLE_TYPE_SIZE / BITS_PER_UNIT);
+  this->c.long_doublesize
+    = (TYPE_PRECISION (long_double_type_node) / BITS_PER_UNIT);
   this->c.wchar_tsize = (WCHAR_TYPE_SIZE / BITS_PER_UNIT);
 
   this->c.bitFieldStyle = targetm.ms_bitfield_layout_p (unknown_type_node)
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 92f3e07f742..ac2d25852ab 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -513,18 +513,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
 #endif
 
-#ifndef FLOAT_TYPE_SIZE
-#define FLOAT_TYPE_SIZE BITS_PER_WORD
-#endif
-
-#ifndef DOUBLE_TYPE_SIZE
-#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
-#endif
-
-#ifndef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
-#endif
-
 #ifndef DECIMAL32_TYPE_SIZE
 #define DECIMAL32_TYPE_SIZE 32
 #endif
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index aa10b5235b5..d85b6dcbf1a 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -1326,7 +1326,7 @@ whose size is @code{BITS_PER_WORD}, @code{SImode} on 32-bit machines.
 
 The only modes which a machine description @i{must} support are
 @code{QImode}, and the modes corresponding to @code{BITS_PER_WORD},
-@code{FLOAT_TYPE_SIZE} and @code{DOUBLE_TYPE_SIZE}.
+C type @code{float} and C type type @code{double}.
 The compiler will attempt to use @code{DImode} for 8-byte structures and
 unions, but this can be prevented by overriding the definition of
 @code{MAX_FIXED_MODE_SIZE}.  Alternatively, you can have the compiler
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index cd50078227d..07bf8ed9e0e 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -1044,6 +1044,14 @@ are zero or sign extended depending on if it is
 @code{GET_MODE_ALIGNMENT (info->limb_mode)}.
 @end deftypefn
 
+@deftypefn {Target Hook} machine_mode TARGET_C_MODE_FOR_FLOATING_TYPE (enum tree_index @var{ti})
+Return machine mode for a C floating point type which is indicated by
+ a given @code{enum tree_index} @var{ti}, @var{ti} should be
+ @code{TI_FLOAT_TYPE}, @code{TI_DOUBLE_TYPE} or @code{TI_LONG_DOUBLE_TYPE}.
+ The default implementation returns @code{SFmode} for @code{TI_FLOAT_TYPE},
+ and @code{DFmode} for @code{TI_DOUBLE_TYPE} or @code{TI_LONG_DOUBLE_TYPE}.
+@end deftypefn
+
 @deftypefn {Target Hook} machine_mode TARGET_PROMOTE_FUNCTION_MODE (const_tree @var{type}, machine_mode @var{mode}, int *@var{punsignedp}, const_tree @var{funtype}, int @var{for_return})
 Like @code{PROMOTE_MODE}, but it is applied to outgoing function arguments or
 function return values.  The target hook should return the new mode
@@ -1610,23 +1618,6 @@ C99 type @code{_Bool} on the target machine.  If you don't define
 this, and you probably shouldn't, the default is @code{CHAR_TYPE_SIZE}.
 @end defmac
 
-@defmac FLOAT_TYPE_SIZE
-A C expression for the size in bits of the type @code{float} on the
-target machine.  If you don't define this, the default is one word.
-@end defmac
-
-@defmac DOUBLE_TYPE_SIZE
-A C expression for the size in bits of the type @code{double} on the
-target machine.  If you don't define this, the default is two
-words.
-@end defmac
-
-@defmac LONG_DOUBLE_TYPE_SIZE
-A C expression for the size in bits of the type @code{long double} on
-the target machine.  If you don't define this, the default is two
-words.
-@end defmac
-
 @defmac SHORT_FRACT_TYPE_SIZE
 A C expression for the size in bits of the type @code{short _Fract} on
 the target machine.  If you don't define this, the default is
@@ -1687,9 +1678,11 @@ the libgcc @file{config.host}.
 @defmac WIDEST_HARDWARE_FP_SIZE
 A C expression for the size in bits of the widest floating-point format
 supported by the hardware.  If you define this macro, you must specify a
-value less than or equal to the value of @code{LONG_DOUBLE_TYPE_SIZE}.
-If you do not define this macro, the value of @code{LONG_DOUBLE_TYPE_SIZE}
-is the default.
+value less than or equal to mode precision of the mode used for C type
+@code{long double} (from hook @code{targetm.c.mode_for_floating_type}
+with tree_index TI_LONG_DOUBLE_TYPE).  If you do not define this macro,
+mode precision of the mode used for C type @code{long double} is the
+default.
 @end defmac
 
 @defmac DEFAULT_SIGNED_CHAR
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 058bd56487a..f6e2372f262 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -947,6 +947,8 @@ applied.
 
 @hook TARGET_C_BITINT_TYPE_INFO
 
+@hook TARGET_C_MODE_FOR_FLOATING_TYPE
+
 @hook TARGET_PROMOTE_FUNCTION_MODE
 
 @defmac PARM_BOUNDARY
@@ -1351,23 +1353,6 @@ C99 type @code{_Bool} on the target machine.  If you don't define
 this, and you probably shouldn't, the default is @code{CHAR_TYPE_SIZE}.
 @end defmac
 
-@defmac FLOAT_TYPE_SIZE
-A C expression for the size in bits of the type @code{float} on the
-target machine.  If you don't define this, the default is one word.
-@end defmac
-
-@defmac DOUBLE_TYPE_SIZE
-A C expression for the size in bits of the type @code{double} on the
-target machine.  If you don't define this, the default is two
-words.
-@end defmac
-
-@defmac LONG_DOUBLE_TYPE_SIZE
-A C expression for the size in bits of the type @code{long double} on
-the target machine.  If you don't define this, the default is two
-words.
-@end defmac
-
 @defmac SHORT_FRACT_TYPE_SIZE
 A C expression for the size in bits of the type @code{short _Fract} on
 the target machine.  If you don't define this, the default is
@@ -1428,9 +1413,11 @@ the libgcc @file{config.host}.
 @defmac WIDEST_HARDWARE_FP_SIZE
 A C expression for the size in bits of the widest floating-point format
 supported by the hardware.  If you define this macro, you must specify a
-value less than or equal to the value of @code{LONG_DOUBLE_TYPE_SIZE}.
-If you do not define this macro, the value of @code{LONG_DOUBLE_TYPE_SIZE}
-is the default.
+value less than or equal to mode precision of the mode used for C type
+@code{long double} (from hook @code{targetm.c.mode_for_floating_type}
+with tree_index TI_LONG_DOUBLE_TYPE).  If you do not define this macro,
+mode precision of the mode used for C type @code{long double} is the
+default.
 @end defmac
 
 @defmac DEFAULT_SIGNED_CHAR
diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc
index 1856fa4884f..cb04aa1a8c6 100644
--- a/gcc/emit-rtl.cc
+++ b/gcc/emit-rtl.cc
@@ -6366,7 +6366,8 @@ init_emit_once (void)
   else
     const_true_rtx = gen_rtx_CONST_INT (VOIDmode, STORE_FLAG_VALUE);
 
-  double_mode = float_mode_for_size (DOUBLE_TYPE_SIZE).require ();
+  mode = targetm.c.mode_for_floating_type (TI_DOUBLE_TYPE);
+  double_mode = as_a<scalar_float_mode> (mode);
 
   real_from_integer (&dconst0, double_mode, 0, SIGNED);
   real_from_integer (&dconst1, double_mode, 1, SIGNED);
diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc
index 80dc3426ab0..6dd25049009 100644
--- a/gcc/fortran/trans-intrinsic.cc
+++ b/gcc/fortran/trans-intrinsic.cc
@@ -395,7 +395,8 @@ build_round_expr (tree arg, tree restype)
      don't have an appropriate function that converts directly to the integer
      type (such as kind == 16), just use ROUND, and then convert the result to
      an integer.  We might also need to convert the result afterwards.  */
-  if (resprec <= INT_TYPE_SIZE && argprec <= LONG_DOUBLE_TYPE_SIZE)
+  if (resprec <= INT_TYPE_SIZE
+      && argprec <= TYPE_PRECISION (long_double_type_node))
     fn = builtin_decl_for_precision (BUILT_IN_IROUND, argprec);
   else if (resprec <= LONG_TYPE_SIZE)
     fn = builtin_decl_for_precision (BUILT_IN_LROUND, argprec);
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index 676014e9b98..85f710f6559 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -873,13 +873,15 @@ gfc_build_real_type (gfc_real_info *info)
   int mode_precision = info->mode_precision;
   tree new_type;
 
-  if (mode_precision == FLOAT_TYPE_SIZE)
+  if (mode_precision == TYPE_PRECISION (float_type_node))
     info->c_float = 1;
-  if (mode_precision == DOUBLE_TYPE_SIZE)
+  if (mode_precision == TYPE_PRECISION (double_type_node))
     info->c_double = 1;
-  if (mode_precision == LONG_DOUBLE_TYPE_SIZE && !info->c_float128)
+  if (mode_precision == TYPE_PRECISION (long_double_type_node)
+      && !info->c_float128)
     info->c_long_double = 1;
-  if (mode_precision != LONG_DOUBLE_TYPE_SIZE && mode_precision == 128)
+  if (mode_precision != TYPE_PRECISION (long_double_type_node)
+      && mode_precision == 128)
     {
       /* TODO: see PR101835.  */
       info->c_float128 = 1;
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index bc9732c3db3..6aa751f9f30 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -993,11 +993,11 @@ Btype*
 Gcc_backend::float_type(int bits)
 {
   tree type;
-  if (bits == FLOAT_TYPE_SIZE)
+  if (bits == TYPE_PRECISION (float_type_node))
     type = float_type_node;
-  else if (bits == DOUBLE_TYPE_SIZE)
+  else if (bits == TYPE_PRECISION (double_type_node))
     type = double_type_node;
-  else if (bits == LONG_DOUBLE_TYPE_SIZE)
+  else if (bits == TYPE_PRECISION (long_double_type_node))
     type = long_double_type_node;
   else
     {
@@ -1014,11 +1014,11 @@ Btype*
 Gcc_backend::complex_type(int bits)
 {
   tree type;
-  if (bits == FLOAT_TYPE_SIZE * 2)
+  if (bits == TYPE_PRECISION (float_type_node) * 2)
     type = complex_float_type_node;
-  else if (bits == DOUBLE_TYPE_SIZE * 2)
+  else if (bits == TYPE_PRECISION (double_type_node) * 2)
     type = complex_double_type_node;
-  else if (bits == LONG_DOUBLE_TYPE_SIZE * 2)
+  else if (bits == TYPE_PRECISION (long_double_type_node) * 2)
     type = complex_long_double_type_node;
   else
     {
diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc
index 68a2e860c1f..7719b898e57 100644
--- a/gcc/jit/jit-recording.cc
+++ b/gcc/jit/jit-recording.cc
@@ -21,7 +21,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
+#include "target.h"
 #include "pretty-print.h"
 #include "toplev.h"
 
@@ -2353,6 +2353,7 @@ size_t
 recording::memento_of_get_type::get_size ()
 {
   int size;
+  machine_mode m;
   switch (m_kind)
     {
     case GCC_JIT_TYPE_VOID:
@@ -2399,13 +2400,16 @@ recording::memento_of_get_type::get_size ()
       size = 128;
       break;
     case GCC_JIT_TYPE_FLOAT:
-      size = FLOAT_TYPE_SIZE;
+      m = targetm.c.mode_for_floating_type (TI_FLOAT_TYPE);
+      size = GET_MODE_PRECISION (m).to_constant ();
       break;
     case GCC_JIT_TYPE_DOUBLE:
-      size = DOUBLE_TYPE_SIZE;
+      m = targetm.c.mode_for_floating_type (TI_DOUBLE_TYPE);
+      size = GET_MODE_PRECISION (m).to_constant ();
       break;
     case GCC_JIT_TYPE_LONG_DOUBLE:
-      size = LONG_DOUBLE_TYPE_SIZE;
+      m = targetm.c.mode_for_floating_type (TI_LONG_DOUBLE_TYPE);
+      size = GET_MODE_PRECISION (m).to_constant ();
       break;
     case GCC_JIT_TYPE_SIZE_T:
       size = MAX_BITS_PER_WORD;
diff --git a/gcc/m2/gm2-gcc/m2type.cc b/gcc/m2/gm2-gcc/m2type.cc
index 571923c08ef..d52cbdf0b99 100644
--- a/gcc/m2/gm2-gcc/m2type.cc
+++ b/gcc/m2/gm2-gcc/m2type.cc
@@ -1420,7 +1420,7 @@ build_m2_short_real_node (void)
   /* Define `REAL'.  */
 
   c = make_node (REAL_TYPE);
-  TYPE_PRECISION (c) = FLOAT_TYPE_SIZE;
+  TYPE_PRECISION (c) = TYPE_PRECISION (float_type_node);
   layout_type (c);
   return c;
 }
@@ -1433,7 +1433,7 @@ build_m2_real_node (void)
   /* Define `REAL'.  */
 
   c = make_node (REAL_TYPE);
-  TYPE_PRECISION (c) = DOUBLE_TYPE_SIZE;
+  TYPE_PRECISION (c) = TYPE_PRECISION (double_type_node);
   layout_type (c);
   return c;
 }
@@ -1447,7 +1447,7 @@ build_m2_long_real_node (void)
   if (M2Options_GetIBMLongDouble ())
     {
       longreal = make_node (REAL_TYPE);
-      TYPE_PRECISION (longreal) = LONG_DOUBLE_TYPE_SIZE;
+      TYPE_PRECISION (longreal) = TYPE_PRECISION (long_double_type_node);
     }
   else if (M2Options_GetIEEELongDouble ())
     longreal = float128_type_node;
diff --git a/gcc/real.h b/gcc/real.h
index 2e40817a2d7..f28022769b3 100644
--- a/gcc/real.h
+++ b/gcc/real.h
@@ -406,9 +406,10 @@ extern const struct real_format arm_bfloat_half_format;
 #define REAL_VALUE_MINUS_ZERO(x)	real_isnegzero (&(x))
 
 /* IN is a REAL_VALUE_TYPE.  OUT is an array of longs.  */
-#define REAL_VALUE_TO_TARGET_LONG_DOUBLE(IN, OUT)			\
-  real_to_target (OUT, &(IN),						\
-		  float_mode_for_size (LONG_DOUBLE_TYPE_SIZE).require ())
+#define REAL_VALUE_TO_TARGET_LONG_DOUBLE(IN, OUT)			   \
+  real_to_target (OUT, &(IN),						   \
+		  float_mode_for_size (TYPE_PRECISION			   \
+				       (long_double_type_node)).require ())
 
 #define REAL_VALUE_TO_TARGET_DOUBLE(IN, OUT) \
   real_to_target (OUT, &(IN), float_mode_for_size (64).require ())
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index f17e19a2dfc..38169c08985 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -411,11 +411,11 @@ tree
 float_type (int bits)
 {
   tree type;
-  if (bits == FLOAT_TYPE_SIZE)
+  if (bits == TYPE_PRECISION (float_type_node))
     type = float_type_node;
-  else if (bits == DOUBLE_TYPE_SIZE)
+  else if (bits == TYPE_PRECISION (double_type_node))
     type = double_type_node;
-  else if (bits == LONG_DOUBLE_TYPE_SIZE)
+  else if (bits == TYPE_PRECISION (long_double_type_node))
     type = long_double_type_node;
   else
     {
diff --git a/gcc/target.def b/gcc/target.def
index c27df8095be..4780ba9c15b 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -6370,6 +6370,15 @@ are zero or sign extended depending on if it is\n\
  bool, (int n, struct bitint_info *info),
  default_bitint_type_info)
 
+DEFHOOK
+(mode_for_floating_type,
+"Return machine mode for a C floating point type which is indicated by\n\
+ a given @code{enum tree_index} @var{ti}, @var{ti} should be\n\
+ @code{TI_FLOAT_TYPE}, @code{TI_DOUBLE_TYPE} or @code{TI_LONG_DOUBLE_TYPE}.\n\
+ The default implementation returns @code{SFmode} for @code{TI_FLOAT_TYPE},\n\
+ and @code{DFmode} for @code{TI_DOUBLE_TYPE} or @code{TI_LONG_DOUBLE_TYPE}.",
+ machine_mode, (enum tree_index ti), default_mode_for_floating_type)
+
 HOOK_VECTOR_END (c)
 
 /* Functions specific to the C++ frontend.  */
diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
index fb339bf75dd..5111e069f0c 100644
--- a/gcc/targhooks.cc
+++ b/gcc/targhooks.cc
@@ -298,6 +298,18 @@ default_mode_for_suffix (char suffix ATTRIBUTE_UNUSED)
   return VOIDmode;
 }
 
+/* Return machine mode for a floating type which is indicated
+   by the given enum tree_index.  */
+
+machine_mode
+default_mode_for_floating_type (enum tree_index ti)
+{
+  if (ti == TI_FLOAT_TYPE)
+    return SFmode;
+  gcc_assert (ti == TI_DOUBLE_TYPE || ti == TI_LONG_DOUBLE_TYPE);
+  return DFmode;
+}
+
 /* The generic C++ ABI specifies this is a 64-bit value.  */
 tree
 default_cxx_guard_type (void)
@@ -449,11 +461,11 @@ default_scalar_mode_supported_p (scalar_mode mode)
       return false;
 
     case MODE_FLOAT:
-      if (precision == FLOAT_TYPE_SIZE)
+      if (mode == targetm.c.mode_for_floating_type (TI_FLOAT_TYPE))
 	return true;
-      if (precision == DOUBLE_TYPE_SIZE)
+      if (mode == targetm.c.mode_for_floating_type (TI_DOUBLE_TYPE))
 	return true;
-      if (precision == LONG_DOUBLE_TYPE_SIZE)
+      if (mode == targetm.c.mode_for_floating_type (TI_LONG_DOUBLE_TYPE))
 	return true;
       return false;
 
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 85f3817c176..fdc17c3b7c0 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -289,6 +289,7 @@ extern unsigned int default_min_arithmetic_precision (void);
 extern enum flt_eval_method
 default_excess_precision (enum excess_precision_type ATTRIBUTE_UNUSED);
 extern bool default_bitint_type_info (int, struct bitint_info *);
+extern machine_mode default_mode_for_floating_type (enum tree_index);
 extern HOST_WIDE_INT default_stack_clash_protection_alloca_probe_range (void);
 extern void default_select_early_remat_modes (sbitmap);
 extern tree default_preferred_else_value (unsigned, tree, unsigned, tree *);
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 9fa74342919..0b5000acb80 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -624,7 +624,7 @@ enum cv_qualifier {
 };
 
 /* Standard named or nameless data types of the C compiler.  */
-enum tree_index {
+enum tree_index : unsigned {
   TI_ERROR_MARK,
   TI_INTQI_TYPE,
   TI_INTHI_TYPE,
@@ -691,17 +691,18 @@ enum tree_index {
   TI_FLOAT64_TYPE,
   TI_FLOAT128_TYPE,
   TI_FLOATN_TYPE_LAST = TI_FLOAT128_TYPE,
-#define NUM_FLOATN_TYPES (TI_FLOATN_TYPE_LAST - TI_FLOATN_TYPE_FIRST + 1)
+#define NUM_FLOATN_TYPES ((int) (TI_FLOATN_TYPE_LAST		\
+				 - TI_FLOATN_TYPE_FIRST + 1))
   TI_FLOAT32X_TYPE,
   TI_FLOATNX_TYPE_FIRST = TI_FLOAT32X_TYPE,
   TI_FLOAT64X_TYPE,
   TI_FLOAT128X_TYPE,
   TI_FLOATNX_TYPE_LAST = TI_FLOAT128X_TYPE,
   TI_FLOATN_NX_TYPE_LAST = TI_FLOAT128X_TYPE,
-#define NUM_FLOATNX_TYPES (TI_FLOATNX_TYPE_LAST - TI_FLOATNX_TYPE_FIRST + 1)
-#define NUM_FLOATN_NX_TYPES (TI_FLOATN_NX_TYPE_LAST		\
-			     - TI_FLOATN_NX_TYPE_FIRST		\
-			     + 1)
+#define NUM_FLOATNX_TYPES ((int) (TI_FLOATNX_TYPE_LAST		\
+				  - TI_FLOATNX_TYPE_FIRST + 1))
+#define NUM_FLOATN_NX_TYPES ((int) (TI_FLOATN_NX_TYPE_LAST	\
+				  - TI_FLOATN_NX_TYPE_FIRST + 1))
 
   /* Type used by certain backends for __float128, which in C++ should be
      distinct type from _Float128 for backwards compatibility reasons.  */
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 6564b002dc1..bc5175f591e 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -9596,15 +9596,27 @@ build_common_tree_nodes (bool signed_char)
   pointer_sized_int_node = build_nonstandard_integer_type (POINTER_SIZE, 1);
 
   float_type_node = make_node (REAL_TYPE);
-  TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE;
+  machine_mode float_type_mode
+    = targetm.c.mode_for_floating_type (TI_FLOAT_TYPE);
+  SET_TYPE_MODE (float_type_node, float_type_mode);
+  TYPE_PRECISION (float_type_node)
+    = GET_MODE_PRECISION (float_type_mode).to_constant ();
   layout_type (float_type_node);
 
   double_type_node = make_node (REAL_TYPE);
-  TYPE_PRECISION (double_type_node) = DOUBLE_TYPE_SIZE;
+  machine_mode double_type_mode
+    = targetm.c.mode_for_floating_type (TI_DOUBLE_TYPE);
+  SET_TYPE_MODE (double_type_node, double_type_mode);
+  TYPE_PRECISION (double_type_node)
+    = GET_MODE_PRECISION (double_type_mode).to_constant ();
   layout_type (double_type_node);
 
   long_double_type_node = make_node (REAL_TYPE);
-  TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE;
+  machine_mode long_double_type_mode
+    = targetm.c.mode_for_floating_type (TI_LONG_DOUBLE_TYPE);
+  SET_TYPE_MODE (long_double_type_node, long_double_type_mode);
+  TYPE_PRECISION (long_double_type_node)
+    = GET_MODE_PRECISION (long_double_type_mode).to_constant ();
   layout_type (long_double_type_node);
 
   for (i = 0; i < NUM_FLOATN_NX_TYPES; i++)
-- 
2.39.3


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC/PATCH] Replace {FLOAT,{,LONG_}DOUBLE}_TYPE_SIZE with new hook
  2024-05-24 10:19         ` [RFC/PATCH] Replace {FLOAT,{,LONG_}DOUBLE}_TYPE_SIZE with new hook Kewen.Lin
@ 2024-05-24 12:23           ` Richard Biener
  2024-05-29  3:27             ` Kewen.Lin
  2024-05-28 21:06           ` Joseph Myers
  1 sibling, 1 reply; 19+ messages in thread
From: Richard Biener @ 2024-05-24 12:23 UTC (permalink / raw)
  To: Kewen.Lin
  Cc: Joseph Myers, GCC Patches, Jakub Jelinek, Richard Sandiford,
	Segher Boessenkool, Peter Bergner, Michael Meissner,
	David Edelsohn

On Fri, May 24, 2024 at 12:20 PM Kewen.Lin <linkw@linux.ibm.com> wrote:
>
> Hi Joseph and Richi,
>
> on 2024/5/13 21:18, Joseph Myers wrote:
> > On Mon, 13 May 2024, Kewen.Lin wrote:
> >
> >>> In fact replacing all of X_TYPE_SIZE with a single hook might be worthwhile
> >>> though this removes the "convenient" defaulting, requiring each target to
> >>> enumerate all standard C ABI type modes.  But that might be also a good thing.
> >>>
> >>
> >> I guess the main value by extending from floating point types to all is to
> >> unify them?  (Assuming that excepting for floating types the others would
> >> not have multiple possible representations like what we faces on 128bit fp).
> >
> > For integer types, giving the number of bits makes sense as an interface -
> > there isn't an issue with different modes.
> >
> > So I think it's appropriate for floating and integer types to have
> > separate hooks - with the one for floating types returning a mode, and the
> > one for integer types returning a number of bits.  (And also keep the
> > existing separate hook for _FloatN / _FloatNx modes.)
> >
> > That may also make for more convenient defaults (whether a target has long
> > double wider than double is largely independent of what sizes it uses for
> > integer types).
> >
>
> Following your suggestion and comments, I made this patch
> for mode_for_floating_type first, considering this touches
> a few FE and port specific code, I think I have to split
> it into a patch series.  Before making that, I'd like to
> ensure this meets what you expected, and also seek for the
> suggestion on how to organize the sub-patches.  There seem
> two ways for sub-patches:
>   1) split this into pieces according to FEs and ports, and
>      squash all of them and commit one patch.
>   2) extract all hook implementation as 1st series (split
>      as ports);
>      extract the hook enablement as 2nd part (split as
>      generic and FEs);
>      the remaining is to remove useless macros (split it
>      as generic and ports);
>
> The 1) is straightforward, while the 2) is fine-grained and
> easy for isolation, but not sure if it's worth doing.
>
> btw, the attached patch is bootstrapped and regtested on
> powerpc64-linux-gnu and powerpc64le-linux-gnu with all
> languages on, cross cc1 built well for affected ports.

Looks reasonable to me - I'd split language changes out but
keep target and middle-end together.  The middle-end parts
look good to me - I'm always a bit nervous when using
size and precision exchangably, esp. for FP, but it seems
this has been done before.

I hope Joseph will eye that part as well.

Thanks for doing this,
Richard.

> BR,
> Kewen
>
> -----

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC/PATCH] Replace {FLOAT,{,LONG_}DOUBLE}_TYPE_SIZE with new hook
  2024-05-24 10:19         ` [RFC/PATCH] Replace {FLOAT,{,LONG_}DOUBLE}_TYPE_SIZE with new hook Kewen.Lin
  2024-05-24 12:23           ` Richard Biener
@ 2024-05-28 21:06           ` Joseph Myers
  1 sibling, 0 replies; 19+ messages in thread
From: Joseph Myers @ 2024-05-28 21:06 UTC (permalink / raw)
  To: Kewen.Lin
  Cc: Richard Biener, GCC Patches, Jakub Jelinek, Richard Sandiford,
	Segher Boessenkool, Peter Bergner, Michael Meissner,
	David Edelsohn

On Fri, 24 May 2024, Kewen.Lin wrote:

> Following your suggestion and comments, I made this patch
> for mode_for_floating_type first, considering this touches
> a few FE and port specific code, I think I have to split
> it into a patch series.  Before making that, I'd like to
> ensure this meets what you expected, and also seek for the

The general idea seems reasonable (I haven't reviewed it in detail).  
Note that when removing a target macro, it's a good idea to add it to the 
"Old target macros that have moved to the target hooks structure." list 
(of #pragma GCC poison) in system.h to ensure any new target that was 
originally written before the change doesn't accidentally get into GCC 
while still using the old macros.

-- 
Joseph S. Myers
josmyers@redhat.com


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC/PATCH] Replace {FLOAT,{,LONG_}DOUBLE}_TYPE_SIZE with new hook
  2024-05-24 12:23           ` Richard Biener
@ 2024-05-29  3:27             ` Kewen.Lin
  2024-05-30 18:10               ` Joseph Myers
  0 siblings, 1 reply; 19+ messages in thread
From: Kewen.Lin @ 2024-05-29  3:27 UTC (permalink / raw)
  To: Richard Biener, Joseph Myers
  Cc: GCC Patches, Jakub Jelinek, Richard Sandiford,
	Segher Boessenkool, Peter Bergner, Michael Meissner,
	David Edelsohn

Hi Richi and Joseph,

on 2024/5/24 20:23, Richard Biener wrote:
> On Fri, May 24, 2024 at 12:20 PM Kewen.Lin <linkw@linux.ibm.com> wrote:
>> btw, the attached patch is bootstrapped and regtested on
>> powerpc64-linux-gnu and powerpc64le-linux-gnu with all
>> languages on, cross cc1 built well for affected ports.
> 
> Looks reasonable to me - I'd split language changes out but
> keep target and middle-end together.  The middle-end parts
> look good to me - I'm always a bit nervous when using
> size and precision exchangably, esp. for FP, but it seems
> this has been done before.

Thanks for the suggestion!  I'll split them into a patch series
as components soon and follow this suggestion when committing
(some preparation language changes go first and squash the
others together).

on 2024/5/29 05:06, Joseph Myers wrote:
> On Fri, 24 May 2024, Kewen.Lin wrote:
> 
>> Following your suggestion and comments, I made this patch
>> for mode_for_floating_type first, considering this touches
>> a few FE and port specific code, I think I have to split
>> it into a patch series.  Before making that, I'd like to
>> ensure this meets what you expected, and also seek for the
> 
> The general idea seems reasonable (I haven't reviewed it in detail).  
> Note that when removing a target macro, it's a good idea to add it to the 
> "Old target macros that have moved to the target hooks structure." list 
> (of #pragma GCC poison) in system.h to ensure any new target that was 
> originally written before the change doesn't accidentally get into GCC 
> while still using the old macros.
> 

Thanks for the comments on target macro removal!  I found it means
that we can't use such macros any more even if they have become port
specific.  For some targets such as pa, they redefine these macros in
some subtarget headers, or these macros get used in other macro
definitions.  Considering leaving them can have better readability,
I didn't try to change them in this RFC/PATCH, I'll update them with
target prefix in the following patch series.

BR,
Kewen


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC/PATCH] Replace {FLOAT,{,LONG_}DOUBLE}_TYPE_SIZE with new hook
  2024-05-29  3:27             ` Kewen.Lin
@ 2024-05-30 18:10               ` Joseph Myers
  0 siblings, 0 replies; 19+ messages in thread
From: Joseph Myers @ 2024-05-30 18:10 UTC (permalink / raw)
  To: Kewen.Lin
  Cc: Richard Biener, GCC Patches, Jakub Jelinek, Richard Sandiford,
	Segher Boessenkool, Peter Bergner, Michael Meissner,
	David Edelsohn

On Wed, 29 May 2024, Kewen.Lin wrote:

> > Note that when removing a target macro, it's a good idea to add it to the 
> > "Old target macros that have moved to the target hooks structure." list 
> > (of #pragma GCC poison) in system.h to ensure any new target that was 
> > originally written before the change doesn't accidentally get into GCC 
> > while still using the old macros.
> > 
> 
> Thanks for the comments on target macro removal!  I found it means
> that we can't use such macros any more even if they have become port
> specific.  For some targets such as pa, they redefine these macros in

Yes, that's intentional.  If you need subtarget headers to define 
something for use in the new target hook for those targets, make them 
define e.g. SUBTARGET_LONG_DOUBLE_MODE or similar instead, rather than 
using the old poisoned macro names.

-- 
Joseph S. Myers
josmyers@redhat.com


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2024-05-30 18:11 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-08  5:21 [PATCH 1/4] rs6000: Make all 128 bit scalar FP modes have 128 bit precision [PR112993] Kewen.Lin
2024-05-08  5:27 ` [PATCH 2/4] fortran: Teach get_real_kind_from_node for Power 128 fp modes [PR112993] Kewen.Lin
2024-05-08  7:40   ` Mikael Morin
2024-05-08 22:01   ` [PATCH 2/4] fortran: Teach get_real_kind_from_node for Power 128 fp modes [PR112993]g Steve Kargl
2024-05-09  5:37     ` Kewen.Lin
2024-05-09 16:47       ` Steve Kargl
2024-05-08  5:32 ` [PATCH 3/4] ranger: Revert the workaround introduced in PR112788 [PR112993] Kewen.Lin
2024-05-08 14:06   ` Aldy Hernandez
2024-05-08  5:36 ` [PATCH 4/4] tree: Remove KFmode workaround [PR112993] Kewen.Lin
2024-05-09 19:12 ` [PATCH 1/4] rs6000: Make all 128 bit scalar FP modes have 128 bit precision [PR112993] Joseph Myers
2024-05-10  6:31   ` Richard Biener
2024-05-13  1:39     ` Kewen.Lin
2024-05-13  7:11       ` Richard Biener
2024-05-13 13:18       ` Joseph Myers
2024-05-24 10:19         ` [RFC/PATCH] Replace {FLOAT,{,LONG_}DOUBLE}_TYPE_SIZE with new hook Kewen.Lin
2024-05-24 12:23           ` Richard Biener
2024-05-29  3:27             ` Kewen.Lin
2024-05-30 18:10               ` Joseph Myers
2024-05-28 21:06           ` Joseph Myers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).