I redid the patch to make the target hook only apply for scalar float points,
and I removed all of the integer only subcases.
I have checked this on a little endian Power8 system, and verified that it
bootstraps correctly and there are no regressions. I have just started an
x86_64 build. Assuming that build has no regressions, can I check this into
GCC 9? This bug appears in GCC 8, and I would like to back port this patch to
GCC 8 as well before GCC 8.2 goes out.
[gcc]
2018-05-25 Michael Meissner <[email protected]>
PR target/85358
* target.def (default_fp_widening_p): New target hook to automatic
widening betwen two floating point modes.
* optabs.c (expand_binop): Do not automatically widen a binary or
unary scalar floating point op if the backend says that the
widening should not occur.
(expand_twoval_unop): Likewise.
(expand_twoval_binop): Likewise.
(expand_unop): Likewise.
* config/rs6000/rs6000.c (TARGET_DEFAULT_FP_WIDENING_P): Define.
(rs6000_default_fp_widening_p): New target hook to prevent
automatic widening between IEEE 128-bit floating point and IBM
extended double floating point.
* doc/tm.texi (Target Hooks): Document new target hook
default_fp_widening_p.
* doc/tm.texi.in (Target Hooks): Likewise.
[gcc/testsuite]
2018-05-25 Michael Meissner <[email protected]>
PR target/85358
* gcc.target/powerpc/pr85358.c: New test.
--
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: [email protected], phone: +1 (978) 899-4797
Index: gcc/target.def
===================================================================
--- gcc/target.def (.../trunk) (revision 260548)
+++ gcc/target.def (.../branches/ibm/ieee) (revision 260765)
@@ -3498,6 +3498,17 @@ If this hook allows @code{val} to have a
hook_bool_mode_uhwi_false)
DEFHOOK
+(default_fp_widening_p,
+ "Return true if GCC can automatically widen @var{mode} to @var{wider_mode}\n\
+if @var{wider_mode} supports an operation in hardware but @var{mode} does\n\
+not. Both modes are scalar floating point modes. The default hook always\n\
+returns true. This hook should be used if all values in @var{mode} cannont\n\
+be represented in @var{wider_mode}, or the rounding characteristics are\n\
+different between the two modes.",
+ bool, (machine_mode wider_mode, machine_mode mode),
+ hook_bool_mode_mode_true)
+
+DEFHOOK
(libgcc_floating_mode_supported_p,
"Define this to return nonzero if libgcc provides support for the \n\
floating-point mode @var{mode}, which is known to pass \n\
Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c (.../trunk) (revision 260548)
+++ gcc/optabs.c (.../branches/ibm/ieee) (revision 260765)
@@ -1284,6 +1284,9 @@ expand_binop (machine_mode mode, optab b
FOR_EACH_WIDER_MODE (wider_mode, mode)
{
machine_mode next_mode;
+ if (SCALAR_FLOAT_MODE_P (mode)
+ && !targetm.default_fp_widening_p (wider_mode, mode))
+ continue;
if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
|| (binoptab == smul_optab
&& GET_MODE_WIDER_MODE (wider_mode).exists (&next_mode)
@@ -1834,6 +1837,9 @@ expand_binop (machine_mode mode, optab b
gcc_assert (!convert_optab_p (binoptab));
FOR_EACH_WIDER_MODE (wider_mode, mode)
{
+ if (SCALAR_FLOAT_MODE_P (mode)
+ && !targetm.default_fp_widening_p (wider_mode, mode))
+ continue;
if (optab_handler (binoptab, wider_mode)
|| (methods == OPTAB_LIB
&& optab_libfunc (binoptab, wider_mode)))
@@ -1989,6 +1995,9 @@ expand_twoval_unop (optab unoptab, rtx o
{
FOR_EACH_WIDER_MODE (wider_mode, mode)
{
+ if (SCALAR_FLOAT_MODE_P (mode)
+ && !targetm.default_fp_widening_p (wider_mode, mode))
+ continue;
if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
{
rtx t0 = gen_reg_rtx (wider_mode);
@@ -2070,6 +2079,9 @@ expand_twoval_binop (optab binoptab, rtx
{
FOR_EACH_WIDER_MODE (wider_mode, mode)
{
+ if (SCALAR_FLOAT_MODE_P (mode)
+ && !targetm.default_fp_widening_p (wider_mode, mode))
+ continue;
if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing)
{
rtx t0 = gen_reg_rtx (wider_mode);
@@ -2865,6 +2877,9 @@ expand_unop (machine_mode mode, optab un
if (CLASS_HAS_WIDER_MODES_P (mclass))
FOR_EACH_WIDER_MODE (wider_mode, mode)
{
+ if (SCALAR_FLOAT_MODE_P (mode)
+ && !targetm.default_fp_widening_p (wider_mode, mode))
+ continue;
if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
{
rtx xop0 = op0;
@@ -3032,6 +3047,9 @@ expand_unop (machine_mode mode, optab un
{
FOR_EACH_WIDER_MODE (wider_mode, mode)
{
+ if (SCALAR_FLOAT_MODE_P (mode)
+ && !targetm.default_fp_widening_p (wider_mode, mode))
+ continue;
if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing
|| optab_libfunc (unoptab, wider_mode))
{
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (.../trunk) (revision 260548)
+++ gcc/config/rs6000/rs6000.c (.../branches/ibm/ieee) (revision 260765)
@@ -1973,6 +1973,9 @@ static const struct attribute_spec rs600
#undef TARGET_STARTING_FRAME_OFFSET
#define TARGET_STARTING_FRAME_OFFSET rs6000_starting_frame_offset
+
+#undef TARGET_DEFAULT_FP_WIDENING_P
+#define TARGET_DEFAULT_FP_WIDENING_P rs6000_default_fp_widening_p
/* Processor table. */
@@ -16497,6 +16505,27 @@ rs6000_init_builtins (void)
#endif
}
+/* Return true if scalar float FROM_MODE can be widened to TO_MODE
+ automatically.
+
+ On PowerPC, don't allow IBM extended double to widen to an IEEE 128-bit
+ floating point value or vice versa. */
+
+static bool
+rs6000_default_fp_widening_p (machine_mode from_mode, machine_mode to_mode)
+{
+ if (!TARGET_FLOAT128_TYPE)
+ return true;
+
+ if (FLOAT128_IEEE_P (from_mode) && FLOAT128_IBM_P (to_mode))
+ return false;
+
+ if (FLOAT128_IBM_P (from_mode) && FLOAT128_IEEE_P (to_mode))
+ return false;
+
+ return true;
+}
+
/* Returns the rs6000 builtin decl for CODE. */
static tree
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi (.../trunk) (revision 260548)
+++ gcc/doc/tm.texi (.../branches/ibm/ieee) (revision 260765)
@@ -4315,6 +4315,15 @@ If this hook allows @code{val} to have a
@code{int8x8x3_t}s in registers rather than forcing them onto the stack.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_DEFAULT_FP_WIDENING_P (machine_mode
@var{wider_mode}, machine_mode @var{mode})
+Return true if GCC can automatically widen @var{mode} to @var{wider_mode}
+if @var{wider_mode} supports an operation in hardware but @var{mode} does
+not. Both modes are scalar floating point modes. The default hook always
+returns true. This hook should be used if all values in @var{mode} cannont
+be represented in @var{wider_mode}, or the rounding characteristics are
+different between the two modes.
+@end deftypefn
+
@deftypefn {Target Hook} bool TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
(scalar_float_mode @var{mode})
Define this to return nonzero if libgcc provides support for the
floating-point mode @var{mode}, which is known to pass
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in (.../trunk) (revision 260548)
+++ gcc/doc/tm.texi.in (.../branches/ibm/ieee) (revision 260765)
@@ -3344,6 +3344,8 @@ stack.
@hook TARGET_ARRAY_MODE_SUPPORTED_P
+@hook TARGET_DEFAULT_FP_WIDENING_P
+
@hook TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
@hook TARGET_FLOATN_MODE
Index: gcc/testsuite/gcc.target/powerpc/pr85358.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr85358.c (.../trunk) (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr85358.c (.../branches/ibm/ieee)
(revision 260765)
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -mfloat128 -O2 -mabi=ieeelongdouble
-Wno-psabi" } */
+
+/* Verify that __ibm128 does not get converted automatically to IEEE 128-bit on
+ machines with IEEE 128-bit hardware support. */
+
+__ibm128
+add (__ibm128 a, __ibm128 b)
+{
+ return a + b;
+}
+
+/* { dg-final { scan-assembler-not {\mxsaddqp\M} } } */