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  <meiss...@linux.ibm.com>

        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  <meiss...@linux.ibm.com>

        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: meiss...@linux.ibm.com, 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} } } */

Reply via email to