diff mbox series

[applied] , 3 PowerPC long double patches applied

Message ID 20180618193437.GA9045@ibm-toto.the-meissners.org
State New
Headers show
Series [applied] , 3 PowerPC long double patches applied | expand

Commit Message

Michael Meissner June 18, 2018, 7:34 p.m. UTC
This is just the combined patch of the last three patches that have been
approved for trunk.  I expanded the description in rs6000-modes.def of what the
3 128-bit floating point types are and why IFmode needs to be ordered above
KFmode and TFmode.

These patches were individually proposed in:
https://gcc.gnu.org/ml/gcc-patches/2018-06/msg00634.html
https://gcc.gnu.org/ml/gcc-patches/2018-06/msg00796.html
https://gcc.gnu.org/ml/gcc-patches/2018-06/msg00799.html

In terms of the tests, the following tests fail if you switch the default long
double format.  At the moment, I don't have the GLIBC that provides native
support for IEEE 128-bit long double:

C tests:
c-c++-common/dfp/cast.c				(_Decimal128 <-> IEEE 128-bit)
c-c++-common/dfp/convert-bfp-11.c		(_Decimal128 <-> IEEE 128-bit)
c-c++-common/dfp/convert-bfp-2.c		(_Decimal128 <-> IEEE 128-bit)
c-c++-common/dfp/convert-bfp-3.c		(_Decimal128 <-> IEEE 128-bit)
c-c++-common/dfp/convert-bfp-4.c		(_Decimal128 <-> IEEE 128-bit)
c-c++-common/dfp/convert-bfp-5.c		(_Decimal128 <-> IEEE 128-bit)
c-c++-common/dfp/convert-bfp-6.c		(_Decimal128 <-> IEEE 128-bit)
c-c++-common/dfp/convert-bfp.c			(_Decimal128 <-> IEEE 128-bit)
c-c++-common/dfp/pr39034.c			(_Decimal128 <-> IEEE 128-bit)
gcc.dg/nextafter-2.c				(needs updated GLIBC)
gcc.dg/torture/float128-nan.c			(I need to investigate this)
gcc.dg/tree-ssa/builtin-sprintf.c		(needs updated GLIBC)
gcc.dg/tree-ssa/vrp104.c			(I need to investigate this)
gcc.target/powerpc/clone1.c			(I have patches for this)
gcc.target/powerpc/clone2.c			(I have patches for this)
gcc.target/powerpc/divkc3-1.c			(I have patches for this)
gcc.target/powerpc/float128-3.c			(I have patches for this)
gcc.target/powerpc/float128-5.c			(I have patches for this)
gcc.target/powerpc/float128-complex-1.c		(I have patches for this)
gcc.target/powerpc/float128-mix.c		(I have patches for this)
gcc.target/powerpc/mulkc3-1.c			(I have patches for this)
gcc.target/powerpc/nan128-1.c			(I need to investigate this)
gcc.target/powerpc/pack02.c			(I have patches for this)
gcc.target/powerpc/pr57150.c			(I have patches for this)
gcc.target/powerpc/pr60203.c			(I have patches for this)
gcc.target/powerpc/pr67808.c			(I have patches for this)
gcc.target/powerpc/pr70117.c			(bug in isnormal on IEEE 128)
gcc.target/powerpc/pr78056-1.c			(I have patches for this)
gcc.target/powerpc/pr78056-3.c			(I have patches for this)
gcc.target/powerpc/pr80210-2.c			(I have patches for this)
gcc.target/powerpc/pr80210.c			(I have patches for this)
gcc.target/powerpc/pr85657-3.c			(I have patches for this)
gcc.target/powerpc/tfmode_off.c			(I have patches for this)

C++ tests:
c-c++-common/dfp/cast.c				(_Decimal128 <-> IEEE 128-bit)
c-c++-common/dfp/convert-bfp-11.c		(_Decimal128 <-> IEEE 128-bit)
c-c++-common/dfp/convert-bfp-2.c		(_Decimal128 <-> IEEE 128-bit)
c-c++-common/dfp/convert-bfp-3.c		(_Decimal128 <-> IEEE 128-bit)
c-c++-common/dfp/convert-bfp-4.c		(_Decimal128 <-> IEEE 128-bit)
c-c++-common/dfp/convert-bfp-5.c		(_Decimal128 <-> IEEE 128-bit)
c-c++-common/dfp/convert-bfp-6.c		(_Decimal128 <-> IEEE 128-bit)
c-c++-common/dfp/convert-bfp.c			(_Decimal128 <-> IEEE 128-bit)
c-c++-common/dfp/pr39034.c			(_Decimal128 <-> IEEE 128-bit)
g++.dg/cdce3.C					(needs updated GLIBC) 

The following Fortran tests fail.  I assume most of these are library issues:
gfortran.dg/erf_3.F90
gfortran.dg/fmt_en.f90
gfortran.dg/fmt_g0_7.f08
gfortran.dg/fmt_pf.f90
gfortran.dg/ieee/large_1.f90
gfortran.dg/ieee/large_3.F90
gfortran.dg/large_real_kind_1.f90
gfortran.dg/large_real_kind_2.F90
gfortran.dg/large_real_kind_3.F90
gfortran.dg/large_real_kind_form_io_1.f90
gfortran.dg/large_real_kind_form_io_2.f90
gfortran.dg/norm2_3.f90
gfortran.dg/quad_2.f90
gfortran.dg/round_2.f03

[gcc]
2018-06-18  Michael Meissner  <meissner@linux.ibm.com>

	PR target/85358
	* config/rs6000/rs6000-modes.def (toplevel): Rework the 128-bit
	floating point modes, so that IFmode is numerically greater than
	TFmode, which is greater than KFmode using FRACTIONAL_FLOAT_MODE
	to declare the ordering.  This prevents IFmode from being
	converted to TFmode when long double is IEEE 128-bit on an ISA 3.0
	machine.  Include rs6000-modes.h to share the fractional values
	between genmodes* and the rest of the compiler.
	(IFmode): Likewise.
	(KFmode): Likewise.
	(TFmode): Likewise.
	* config/rs6000/rs6000-modes.h: New file.
	* config/rs6000/rs6000.c (rs6000_debug_reg_global): Change the
	meaning of rs6000_long_double_size so that 126..128 selects an
	appropriate 128-bit floating point type.
	(rs6000_option_override_internal): Likewise.
	* config/rs6000/rs6000.h (toplevel): Include rs6000-modes.h.
	(TARGET_LONG_DOUBLE_128): Change the meaning of
	rs6000_long_double_size so that 126..128 selects an appropriate
	128-bit floating point type.
	(LONG_DOUBLE_TYPE_SIZE): Update comment.
	* config/rs6000/rs6000.md (trunciftf2): Correct the modes of the
	source and destination to match the standard usage.
	(truncifkf2): Likewise.
	(copysign<mode>3, IEEE iterator): Rework copysign of float128 on
	ISA 2.07 to use an explicit clobber, instead of passing in a
	temporary.
	(copysign<mode>3_soft): Likewise.

[libgcc]
2018-06-18  Michael Meissner  <meissner@linux.ibm.com>

	* config/rs6000/t-float128 (FP128_CFLAGS_SW): Compile float128
	support modules with -mno-gnu-attribute.
	* config/rs6000/t-float128-hw (FP128_CFLAGS_HW): Likewise.

Comments

Joseph Myers June 18, 2018, 7:40 p.m. UTC | #1
On Mon, 18 Jun 2018, Michael Meissner wrote:

> gcc.target/powerpc/pr70117.c			(bug in isnormal on IEEE 128)

Doesn't look like a bug in isnormal to me.  That test is explicitly using 
an IBM long double representation and can't possibly be expected to work 
with IEEE long double - either it needs to be disabled for IEEE long 
double, or to use -mabi=ibmlongdouble explicitly, or to use __ibm128 (but 
if you use __ibm128 you can't then test the type-specific __builtin_isinfl 
like it does at present).
Michael Meissner June 18, 2018, 7:48 p.m. UTC | #2
On Mon, Jun 18, 2018 at 07:40:46PM +0000, Joseph Myers wrote:
> On Mon, 18 Jun 2018, Michael Meissner wrote:
> 
> > gcc.target/powerpc/pr70117.c			(bug in isnormal on IEEE 128)
> 
> Doesn't look like a bug in isnormal to me.  That test is explicitly using 
> an IBM long double representation and can't possibly be expected to work 
> with IEEE long double - either it needs to be disabled for IEEE long 
> double, or to use -mabi=ibmlongdouble explicitly, or to use __ibm128 (but 
> if you use __ibm128 you can't then test the type-specific __builtin_isinfl 
> like it does at present).

I've fixed the test to use __ibm128 already in my branch.  The issue is the
compiler generates different code for __ibm128 (when long double is IEEE
128-bit) than it does for long double using IBM extended double.  The code
fails for __ibm128, but does not fail normally.

I haven't fully investigated why the code is different.
Joseph Myers June 18, 2018, 7:56 p.m. UTC | #3
On Mon, 18 Jun 2018, Michael Meissner wrote:

> In terms of the tests, the following tests fail if you switch the default long
> double format.

Also, having done a test build: various *tf* and *tc* libgcc functions end 
up getting built incorrectly (to use IEEE long double when the ABIs for 
those functions are supposed to use IBM long double) if you switch the 
default long double format.  This affects at least __multc3 __divtc3 
__powitf2 __fix{,uns}tf{di,ti} __float{,un}{di,ti}tf.
Segher Boessenkool June 19, 2018, 9:24 p.m. UTC | #4
On Mon, Jun 18, 2018 at 03:34:37PM -0400, Michael Meissner wrote:
> This is just the combined patch of the last three patches that have been
> approved for trunk.  I expanded the description in rs6000-modes.def of what the
> 3 128-bit floating point types are and why IFmode needs to be ordered above
> KFmode and TFmode.
> 
> These patches were individually proposed in:
> https://gcc.gnu.org/ml/gcc-patches/2018-06/msg00634.html
> https://gcc.gnu.org/ml/gcc-patches/2018-06/msg00796.html
> https://gcc.gnu.org/ml/gcc-patches/2018-06/msg00799.html
> 
> In terms of the tests, the following tests fail if you switch the default long
> double format.  At the moment, I don't have the GLIBC that provides native
> support for IEEE 128-bit long double:

<snip>

Is this a regression, or do those failures happen on trunk with default
ieee128 long double already?


Segher
diff mbox series

Patch

Index: gcc/config/rs6000/rs6000-modes.def
===================================================================
--- gcc/config/rs6000/rs6000-modes.def	(revision 261708)
+++ gcc/config/rs6000/rs6000-modes.def	(working copy)
@@ -18,16 +18,39 @@ 
    along with GCC; see the file COPYING3.  If not see
    <http://www.gnu.org/licenses/>.  */
 
-/* IBM 128-bit floating point.  IFmode and KFmode use the fractional float
-   support in order to declare 3 128-bit floating point types.  */
-FRACTIONAL_FLOAT_MODE (IF, 106, 16, ibm_extended_format);
+/* 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.
+
+   Previously, IFmode and KFmode were defined to be fractional modes and TFmode
+   was the standard mode.  Since IFmode does not define the normal arithmetic
+   insns (other than neg/abs), on a ISA 3.0 system, the machine independent
+   parts of the compiler would see that TFmode has the necessary hardware
+   support, and widen the operation from IFmode to TFmode.  However, IEEE
+   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);
 
 /* Explicit IEEE 128-bit floating point.  */
-FRACTIONAL_FLOAT_MODE (KF, 113, 16, ieee_quad_format);
+FRACTIONAL_FLOAT_MODE (KF, FLOAT_PRECISION_KFmode, 16, ieee_quad_format);
 
-/* 128-bit floating point.  ABI_V4 uses IEEE quad, AIX/Darwin
-   adjust this in rs6000_option_override_internal.  */
-FLOAT_MODE (TF, 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);
 
 /* Add any extra modes needed to represent the condition code.
 
Index: gcc/config/rs6000/rs6000-modes.h
===================================================================
--- gcc/config/rs6000/rs6000-modes.h	(nonexistent)
+++ gcc/config/rs6000/rs6000-modes.h	(working copy)
@@ -0,0 +1,36 @@ 
+/* Definitions 128-bit floating point precisions used by PowerPC.
+   Copyright (C) 2018 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 */
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 261708)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -2887,7 +2887,7 @@  rs6000_debug_reg_global (void)
   fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
   fprintf (stderr, DEBUG_FMT_D, "long_double_size",
 	   rs6000_long_double_type_size);
-  if (rs6000_long_double_type_size == 128)
+  if (rs6000_long_double_type_size > 64)
     {
       fprintf (stderr, DEBUG_FMT_S, "long double type",
 	       TARGET_IEEEQUAD ? "IEEE" : "IBM");
@@ -4558,16 +4558,25 @@  rs6000_option_override_internal (bool gl
 	}
     }
 
+  /* Use long double size to select the appropriate long double.  We use
+     TYPE_PRECISION to differentiate the 3 different long double types.  We map
+     128 into the precision used for TFmode.  */
+  int default_long_double_size = (RS6000_DEFAULT_LONG_DOUBLE_SIZE == 64
+				  ? 64
+				  : FLOAT_PRECISION_TFmode);
+
   /* Set long double size before the IEEE 128-bit tests.  */
   if (!global_options_set.x_rs6000_long_double_type_size)
     {
       if (main_target_opt != NULL
 	  && (main_target_opt->x_rs6000_long_double_type_size
-	      != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
+	      != default_long_double_size))
 	error ("target attribute or pragma changes long double size");
       else
-	rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
+	rs6000_long_double_type_size = default_long_double_size;
     }
+  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
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(revision 261708)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -30,6 +30,11 @@ 
 #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.  */
 
@@ -539,7 +544,9 @@  extern int rs6000_vector_align[];
 #define TARGET_ALIGN_NATURAL 0
 #endif
 
-#define TARGET_LONG_DOUBLE_128 (rs6000_long_double_type_size == 128)
+/* We use values 126..128 to pick the appropriate long double type (IFmode,
+   KFmode, TFmode).  */
+#define TARGET_LONG_DOUBLE_128 (rs6000_long_double_type_size > 64)
 #define TARGET_IEEEQUAD rs6000_ieeequad
 #define TARGET_ALTIVEC_ABI rs6000_altivec_abi
 #define TARGET_LDBRX (TARGET_POPCNTD || rs6000_cpu == PROCESSOR_CELL)
@@ -865,9 +872,8 @@  extern unsigned char rs6000_recip_bits[]
    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.  */
+/* 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.c.  */
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 261708)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -8159,8 +8159,8 @@  (define_expand "extendtfkf2"
 })
 
 (define_expand "trunciftf2"
-  [(set (match_operand:IF 0 "gpc_reg_operand")
-	(float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
+  [(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);
@@ -8168,8 +8168,8 @@  (define_expand "trunciftf2"
 })
 
 (define_expand "truncifkf2"
-  [(set (match_operand:IF 0 "gpc_reg_operand")
-	(float_truncate:IF (match_operand:KF 1 "gpc_reg_operand")))]
+  [(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);
@@ -14102,11 +14102,8 @@  (define_expand "copysign<mode>3"
     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
 					 operands[2]));
   else
-    {
-      rtx tmp = gen_reg_rtx (<MODE>mode);
-      emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
-					   operands[2], tmp));
-    }
+    emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
+					 operands[2]));
   DONE;
 })
 
@@ -14125,9 +14122,9 @@  (define_insn "copysign<mode>3_soft"
   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
 	(unspec:IEEE128
 	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
-	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
-	  (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
-	 UNSPEC_COPYSIGN))]
+	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
+	 UNSPEC_COPYSIGN))
+   (clobber (match_scratch:IEEE128 3 "=&v"))]
   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
   [(set_attr "type" "veccomplex")
Index: libgcc/config/rs6000/t-float128
===================================================================
--- libgcc/config/rs6000/t-float128	(revision 261708)
+++ libgcc/config/rs6000/t-float128	(working copy)
@@ -59,7 +59,7 @@  fp128_includes		= $(srcdir)/soft-fp/doub
 
 # Build the emulator without ISA 3.0 hardware support.
 FP128_CFLAGS_SW		 = -Wno-type-limits -mvsx -mfloat128 \
-			   -mno-float128-hardware \
+			   -mno-float128-hardware -mno-gnu-attribute \
 			   -I$(srcdir)/soft-fp \
 			   -I$(srcdir)/config/rs6000 \
 			   $(FLOAT128_HW_INSNS)
Index: libgcc/config/rs6000/t-float128-hw
===================================================================
--- libgcc/config/rs6000/t-float128-hw	(revision 261708)
+++ libgcc/config/rs6000/t-float128-hw	(working copy)
@@ -25,7 +25,7 @@  fp128_sed_hw		= -hw
 # Build the hardware support functions with appropriate hardware support
 FP128_CFLAGS_HW		 = -Wno-type-limits -mvsx -mfloat128 \
 			   -mpower8-vector -mpower9-vector \
-			   -mfloat128-hardware \
+			   -mfloat128-hardware -mno-gnu-attribute \
 			   -I$(srcdir)/soft-fp \
 			   -I$(srcdir)/config/rs6000 \
 			   $(FLOAT128_HW_INSNS)