re PR target/85358 (PowerPC: Using -mabi=ieeelongdouble -mcpu=power9 breaks __ibm128)

[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.

From-SVN: r261712
This commit is contained in:
Michael Meissner 2018-06-18 19:10:08 +00:00 committed by Michael Meissner
parent b0874c667d
commit 6a8886e45f
9 changed files with 136 additions and 28 deletions

View File

@ -1,3 +1,34 @@
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.
2018-06-18 David Malcolm <dmalcolm@redhat.com>
* tree-vect-data-refs.c (vect_analyze_data_ref_dependences):

View File

@ -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.

View File

@ -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 */

View File

@ -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 global_init_p)
}
}
/* 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

View File

@ -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. */

View File

@ -8159,8 +8159,8 @@
})
(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 "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 @@
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 @@
[(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")

View File

@ -1,3 +1,9 @@
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.
2018-06-07 Olivier Hainque <hainque@adacore.com>
* config/t-vxworks (LIBGCC_INCLUDES): Add

View File

@ -59,7 +59,7 @@ fp128_includes = $(srcdir)/soft-fp/double.h \
# 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)

View File

@ -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)