https://gcc.gnu.org/g:33dca0a4c1c421625cedb2d6105ef1c05f6b774e

commit r15-2084-g33dca0a4c1c421625cedb2d6105ef1c05f6b774e
Author: Kewen Lin <li...@linux.ibm.com>
Date:   Wed Jul 17 00:14:43 2024 -0500

    rs6000: Make all 128 bit scalar FP modes have 128 bit precision [PR112993]
    
    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.  Besides, build_common_tree_nodes
    adopts the newly added hook mode_for_floating_type so we
    don't need to worry about unexpected mode for long double
    type node.
    
    In function convert_mode_scalar, with the proposed change,
    it adopts sext_optab for converting ieee128 format mode to
    ibm128 format mode while trunc_optab for converting ibm128
    format mode to ieee128 format mode.  Thus this patch removes
    useless extend and trunc optab supports, supplements new
    define_expands expandkftf2 and trunctfkf2 to align with
    convert_mode_scalar implementation.  It also 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.
    
    [1] https://inbox.sourceware.org/gcc-patches/
        718677e7-614d-7977-312d-05a75e1fd...@linux.ibm.com/
    
            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.
            (rs6000_c_mode_for_floating_type): Likewise.
            * config/rs6000/rs6000.md (define_expand extendiftf2): Remove.
            (define_expand extendifkf2): Remove.
            (define_expand extendtfkf2): Remove.
            (define_expand trunckftf2): Remove.
            (define_expand trunctfif2): Remove.
            (define_expand extendtfif2): Add new assertion.
            (define_expand expandkftf2): New.
            (define_expand trunciftf2): Add new assertion.
            (define_expand trunctfkf2): New.
            (define_expand truncifkf2): Change with gcc_unreachable.
            (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.

Diff:
---
 gcc/config/rs6000/rs6000-modes.def | 31 +++++++-----------
 gcc/config/rs6000/rs6000-modes.h   | 36 --------------------
 gcc/config/rs6000/rs6000.cc        |  9 ++---
 gcc/config/rs6000/rs6000.h         |  5 ---
 gcc/config/rs6000/rs6000.md        | 67 +++++++++++++++-----------------------
 gcc/config/rs6000/t-rs6000         |  1 -
 6 files changed, 41 insertions(+), 108 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-modes.def 
b/gcc/config/rs6000/rs6000-modes.def
index 094b246c834d..b69593c40a61 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 cf95330c2650..000000000000
--- 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 (meiss...@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 d4eec5c472f8..905e6cb6a942 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -4103,7 +4103,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))
@@ -4115,10 +4115,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
@@ -24400,8 +24396,7 @@ 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 rs6000_long_double_type_size == 128 ? TFmode : DFmode;
   return default_mode_for_floating_type (ti);
 }
 
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 9211f91740a2..8ea9ac1707ea 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 45a4a8cfb907..6a2891c5e509 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -9334,41 +9334,28 @@
   "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"
-  [(set (match_operand:TF 0 "gpc_reg_operand")
-       (float_extend:TF (match_operand:IF 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")))]
+; 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 converting IEEE 128-bit
+; to IBM double double while trunc_optab for converting
+; IBM double double to IEEE 128-bit.
+(define_expand "extendtfif2"
+  [(set (match_operand:IF 0 "gpc_reg_operand")
+       (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
+  gcc_assert (TARGET_IEEEQUAD);
   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")))]
+(define_expand "extendkftf2"
+  [(set (match_operand:TF 0 "gpc_reg_operand")
+       (float_extend:TF (match_operand:KF 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
+  gcc_assert (!TARGET_IEEEQUAD);
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
 })
@@ -9378,35 +9365,35 @@
        (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
+  gcc_assert (TARGET_IEEEQUAD);
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
 })
 
-(define_expand "truncifkf2"
+(define_expand "trunctfkf2"
   [(set (match_operand:KF 0 "gpc_reg_operand")
-       (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
+       (float_truncate:KF (match_operand:TF 1 "gpc_reg_operand")))]
   "TARGET_FLOAT128_TYPE"
 {
+  gcc_assert (!TARGET_IEEEQUAD);
   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")))]
+(define_expand "truncifkf2"
+  [(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;
+  gcc_unreachable ();
 })
 
-(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_unreachable ();
 })
 
 (define_insn_and_split "*extend<mode>tf2_internal"
@@ -15173,7 +15160,7 @@
 
 ;; 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"
@@ -15189,7 +15176,7 @@
   [(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 b3ce09d523be..155788de40a3 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

Reply via email to