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:
parent
b0874c667d
commit
6a8886e45f
|
@ -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>
|
2018-06-18 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
* tree-vect-data-refs.c (vect_analyze_data_ref_dependences):
|
* tree-vect-data-refs.c (vect_analyze_data_ref_dependences):
|
||||||
|
|
|
@ -18,16 +18,39 @@
|
||||||
along with GCC; see the file COPYING3. If not see
|
along with GCC; see the file COPYING3. If not see
|
||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
/* IBM 128-bit floating point. IFmode and KFmode use the fractional float
|
/* We order the 3 128-bit floating point types so that IFmode (IBM 128-bit
|
||||||
support in order to declare 3 128-bit floating point types. */
|
floating point) is the 128-bit floating point type with the highest
|
||||||
FRACTIONAL_FLOAT_MODE (IF, 106, 16, ibm_extended_format);
|
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. */
|
/* 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
|
/* 128-bit floating point, either IBM 128-bit or IEEE 128-bit. This is
|
||||||
adjust this in rs6000_option_override_internal. */
|
adjusted in rs6000_option_override_internal to be the appropriate floating
|
||||||
FLOAT_MODE (TF, 16, ieee_quad_format);
|
point type. */
|
||||||
|
FRACTIONAL_FLOAT_MODE (TF, FLOAT_PRECISION_TFmode, 16, ieee_quad_format);
|
||||||
|
|
||||||
/* Add any extra modes needed to represent the condition code.
|
/* Add any extra modes needed to represent the condition code.
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
|
@ -2887,7 +2887,7 @@ rs6000_debug_reg_global (void)
|
||||||
fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
|
fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
|
||||||
fprintf (stderr, DEBUG_FMT_D, "long_double_size",
|
fprintf (stderr, DEBUG_FMT_D, "long_double_size",
|
||||||
rs6000_long_double_type_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",
|
fprintf (stderr, DEBUG_FMT_S, "long double type",
|
||||||
TARGET_IEEEQUAD ? "IEEE" : "IBM");
|
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. */
|
/* Set long double size before the IEEE 128-bit tests. */
|
||||||
if (!global_options_set.x_rs6000_long_double_type_size)
|
if (!global_options_set.x_rs6000_long_double_type_size)
|
||||||
{
|
{
|
||||||
if (main_target_opt != NULL
|
if (main_target_opt != NULL
|
||||||
&& (main_target_opt->x_rs6000_long_double_type_size
|
&& (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");
|
error ("target attribute or pragma changes long double size");
|
||||||
else
|
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
|
/* 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
|
systems will also set long double to be IEEE 128-bit. AIX and Darwin
|
||||||
|
|
|
@ -30,6 +30,11 @@
|
||||||
#include "config/rs6000/rs6000-opts.h"
|
#include "config/rs6000/rs6000-opts.h"
|
||||||
#endif
|
#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
|
/* Definitions for the object file format. These are set at
|
||||||
compile-time. */
|
compile-time. */
|
||||||
|
|
||||||
|
@ -539,7 +544,9 @@ extern int rs6000_vector_align[];
|
||||||
#define TARGET_ALIGN_NATURAL 0
|
#define TARGET_ALIGN_NATURAL 0
|
||||||
#endif
|
#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_IEEEQUAD rs6000_ieeequad
|
||||||
#define TARGET_ALTIVEC_ABI rs6000_altivec_abi
|
#define TARGET_ALTIVEC_ABI rs6000_altivec_abi
|
||||||
#define TARGET_LDBRX (TARGET_POPCNTD || rs6000_cpu == PROCESSOR_CELL)
|
#define TARGET_LDBRX (TARGET_POPCNTD || rs6000_cpu == PROCESSOR_CELL)
|
||||||
|
@ -865,9 +872,8 @@ extern unsigned char rs6000_recip_bits[];
|
||||||
words. */
|
words. */
|
||||||
#define DOUBLE_TYPE_SIZE 64
|
#define DOUBLE_TYPE_SIZE 64
|
||||||
|
|
||||||
/* A C expression for the size in bits of the type `long double' on
|
/* A C expression for the size in bits of the type `long double' on the target
|
||||||
the target machine. If you don't define this, the default is two
|
machine. If you don't define this, the default is two words. */
|
||||||
words. */
|
|
||||||
#define LONG_DOUBLE_TYPE_SIZE rs6000_long_double_type_size
|
#define LONG_DOUBLE_TYPE_SIZE rs6000_long_double_type_size
|
||||||
|
|
||||||
/* Work around rs6000_long_double_type_size dependency in ada/targtyps.c. */
|
/* Work around rs6000_long_double_type_size dependency in ada/targtyps.c. */
|
||||||
|
|
|
@ -8159,8 +8159,8 @@
|
||||||
})
|
})
|
||||||
|
|
||||||
(define_expand "trunciftf2"
|
(define_expand "trunciftf2"
|
||||||
[(set (match_operand:IF 0 "gpc_reg_operand")
|
[(set (match_operand:TF 0 "gpc_reg_operand")
|
||||||
(float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
|
(float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
|
||||||
"TARGET_FLOAT128_TYPE"
|
"TARGET_FLOAT128_TYPE"
|
||||||
{
|
{
|
||||||
rs6000_expand_float128_convert (operands[0], operands[1], false);
|
rs6000_expand_float128_convert (operands[0], operands[1], false);
|
||||||
|
@ -8168,8 +8168,8 @@
|
||||||
})
|
})
|
||||||
|
|
||||||
(define_expand "truncifkf2"
|
(define_expand "truncifkf2"
|
||||||
[(set (match_operand:IF 0 "gpc_reg_operand")
|
[(set (match_operand:KF 0 "gpc_reg_operand")
|
||||||
(float_truncate:IF (match_operand:KF 1 "gpc_reg_operand")))]
|
(float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
|
||||||
"TARGET_FLOAT128_TYPE"
|
"TARGET_FLOAT128_TYPE"
|
||||||
{
|
{
|
||||||
rs6000_expand_float128_convert (operands[0], operands[1], false);
|
rs6000_expand_float128_convert (operands[0], operands[1], false);
|
||||||
|
@ -14102,11 +14102,8 @@
|
||||||
emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
|
emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
|
||||||
operands[2]));
|
operands[2]));
|
||||||
else
|
else
|
||||||
{
|
emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
|
||||||
rtx tmp = gen_reg_rtx (<MODE>mode);
|
operands[2]));
|
||||||
emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
|
|
||||||
operands[2], tmp));
|
|
||||||
}
|
|
||||||
DONE;
|
DONE;
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -14125,9 +14122,9 @@
|
||||||
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
|
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
|
||||||
(unspec:IEEE128
|
(unspec:IEEE128
|
||||||
[(match_operand:IEEE128 1 "altivec_register_operand" "v")
|
[(match_operand:IEEE128 1 "altivec_register_operand" "v")
|
||||||
(match_operand:IEEE128 2 "altivec_register_operand" "v")
|
(match_operand:IEEE128 2 "altivec_register_operand" "v")]
|
||||||
(match_operand:IEEE128 3 "altivec_register_operand" "+v")]
|
UNSPEC_COPYSIGN))
|
||||||
UNSPEC_COPYSIGN))]
|
(clobber (match_scratch:IEEE128 3 "=&v"))]
|
||||||
"!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
|
"!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
|
||||||
"xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
|
"xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
|
||||||
[(set_attr "type" "veccomplex")
|
[(set_attr "type" "veccomplex")
|
||||||
|
|
|
@ -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>
|
2018-06-07 Olivier Hainque <hainque@adacore.com>
|
||||||
|
|
||||||
* config/t-vxworks (LIBGCC_INCLUDES): Add
|
* config/t-vxworks (LIBGCC_INCLUDES): Add
|
||||||
|
|
|
@ -59,7 +59,7 @@ fp128_includes = $(srcdir)/soft-fp/double.h \
|
||||||
|
|
||||||
# Build the emulator without ISA 3.0 hardware support.
|
# Build the emulator without ISA 3.0 hardware support.
|
||||||
FP128_CFLAGS_SW = -Wno-type-limits -mvsx -mfloat128 \
|
FP128_CFLAGS_SW = -Wno-type-limits -mvsx -mfloat128 \
|
||||||
-mno-float128-hardware \
|
-mno-float128-hardware -mno-gnu-attribute \
|
||||||
-I$(srcdir)/soft-fp \
|
-I$(srcdir)/soft-fp \
|
||||||
-I$(srcdir)/config/rs6000 \
|
-I$(srcdir)/config/rs6000 \
|
||||||
$(FLOAT128_HW_INSNS)
|
$(FLOAT128_HW_INSNS)
|
||||||
|
|
|
@ -25,7 +25,7 @@ fp128_sed_hw = -hw
|
||||||
# Build the hardware support functions with appropriate hardware support
|
# Build the hardware support functions with appropriate hardware support
|
||||||
FP128_CFLAGS_HW = -Wno-type-limits -mvsx -mfloat128 \
|
FP128_CFLAGS_HW = -Wno-type-limits -mvsx -mfloat128 \
|
||||||
-mpower8-vector -mpower9-vector \
|
-mpower8-vector -mpower9-vector \
|
||||||
-mfloat128-hardware \
|
-mfloat128-hardware -mno-gnu-attribute \
|
||||||
-I$(srcdir)/soft-fp \
|
-I$(srcdir)/soft-fp \
|
||||||
-I$(srcdir)/config/rs6000 \
|
-I$(srcdir)/config/rs6000 \
|
||||||
$(FLOAT128_HW_INSNS)
|
$(FLOAT128_HW_INSNS)
|
||||||
|
|
Loading…
Reference in New Issue