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