From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1005) id C48A03858413; Wed, 25 Jan 2023 02:59:49 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C48A03858413 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1674615589; bh=sBfdggQFFlEWApbdcM+JaF6tmD7/jKfBqat+lXWrAsk=; h=From:To:Subject:Date:From; b=pH0Ze7B52QomTWPLynHoCDIL9tl6caD4d0O7sV0jboVvpdhnPB46WjJgYYJvMQ9sF Pw5vXkUVqeWTNj8yYs6aGchuMBwLKax+WUPIiM9mhf7BoXIIILt0wcWk3D3KT7wzqh 4eD5lv1nkFJNC4fMkE79BZeqtiOGRMGnWH3uKTcI= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Michael Meissner To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/meissner/heads/work107)] Improve PowerPC 128-bit floating point types. X-Act-Checkin: gcc X-Git-Author: Michael Meissner X-Git-Refname: refs/users/meissner/heads/work107 X-Git-Oldrev: 7f92b918e931ad6c26ea72e14f310d0fde3ec684 X-Git-Newrev: 2addd92c25c5b5cc9f223a9cb377ccc6aae52c99 Message-Id: <20230125025949.C48A03858413@sourceware.org> Date: Wed, 25 Jan 2023 02:59:49 +0000 (GMT) List-Id: https://gcc.gnu.org/g:2addd92c25c5b5cc9f223a9cb377ccc6aae52c99 commit 2addd92c25c5b5cc9f223a9cb377ccc6aae52c99 Author: Michael Meissner Date: Tue Jan 24 21:59:29 2023 -0500 Improve PowerPC 128-bit floating point types. This patch prevents __ibm128 and __float128 from being considered in the automatic widening that the compiler does. This way, you don't have the possibility that IFmode (__ibm128) will be widened to TFmode or KFmode, even there is hardware to support the IEEE 128-bit operations. I also moved changing the TFmode format from ieee to ibm to rs6000-modes.def from rs6000.cc. 2022-01-24 Michael Meissner gcc/ * config/rs6000/rs6000-modes.def (IFmode): Rework to use FRACTIONAL_FLOAT_MODE_NO_WIDEN. (KFmode): Likewise. * expr.cc (convert_mode_scalar): Don't abort if we are converting floating point modes that are the same precision but use different encodings. * genmodes.cc (struct mode_data): Add support for no widening. (blank_mode): Likewise. (FRACTIONAL_FLOAT_MODE): Add support for no widening capability. (FRACTIONAL_FLOAT_MODE_NO_WIDEN): New macro. (make_float_mode): Add support for no widening capability. (cmp_modes): Likewise. (emit_mode_wider): Add support for no widening capability. * machmode.def (FRACTIONAL_FLOAT_MODE_NO_WIDEN): Document. Diff: --- gcc/config/rs6000/rs6000-modes.def | 6 +++-- gcc/expr.cc | 6 ++--- gcc/genmodes.cc | 53 ++++++++++++++++++++++++++++---------- gcc/machmode.def | 6 +++++ 4 files changed, 52 insertions(+), 19 deletions(-) diff --git a/gcc/config/rs6000/rs6000-modes.def b/gcc/config/rs6000/rs6000-modes.def index 73dfde5c6e7..9885e0d7def 100644 --- a/gcc/config/rs6000/rs6000-modes.def +++ b/gcc/config/rs6000/rs6000-modes.def @@ -42,10 +42,12 @@ #endif /* IBM 128-bit floating point. */ -FRACTIONAL_FLOAT_MODE (IF, FLOAT_PRECISION_IFmode, 16, ibm_extended_format); +FRACTIONAL_FLOAT_MODE_NO_WIDEN (IF, FLOAT_PRECISION_IFmode, 16, + ibm_extended_format); /* Explicit IEEE 128-bit floating point. */ -FRACTIONAL_FLOAT_MODE (KF, FLOAT_PRECISION_KFmode, 16, ieee_quad_format); +FRACTIONAL_FLOAT_MODE_NO_WIDEN (KF, FLOAT_PRECISION_KFmode, 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 diff --git a/gcc/expr.cc b/gcc/expr.cc index 15be1c8db99..c1c1e9729e8 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -345,10 +345,8 @@ convert_mode_scalar (rtx to, rtx from, int unsignedp) != GET_MODE_PRECISION (to_mode)) || (DECIMAL_FLOAT_MODE_P (from_mode) != DECIMAL_FLOAT_MODE_P (to_mode)) - || (REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format - && REAL_MODE_FORMAT (to_mode) == &ieee_half_format) - || (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format - && REAL_MODE_FORMAT (from_mode) == &ieee_half_format)); + || (REAL_MODE_FORMAT (from_mode) + != REAL_MODE_FORMAT (to_mode))); if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode)) /* Conversion between decimal float and binary float, same size. */ diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc index 2d418f09aab..ff0bd763a12 100644 --- a/gcc/genmodes.cc +++ b/gcc/genmodes.cc @@ -79,6 +79,8 @@ struct mode_data adjustment */ unsigned int int_n; /* If nonzero, then __int will be defined */ bool boolean; + bool normal_widen; /* Whether the type should be listed in the + mode_wider and mode_2xwider tables. */ }; static struct mode_data *modes[MAX_MODE_CLASS]; @@ -90,7 +92,7 @@ static const struct mode_data blank_mode = { 0, -1U, -1U, -1U, -1U, 0, 0, 0, 0, 0, 0, "", 0, 0, 0, 0, false, false, 0, - false + false, true }; static htab_t modes_by_name; @@ -658,18 +660,22 @@ make_fixed_point_mode (enum mode_class cl, #define FLOAT_MODE(N, Y, F) FRACTIONAL_FLOAT_MODE (N, -1U, Y, F) #define FRACTIONAL_FLOAT_MODE(N, B, Y, F) \ - make_float_mode (#N, B, Y, #F, __FILE__, __LINE__) + make_float_mode (#N, B, Y, #F, __FILE__, __LINE__, true) +#define FRACTIONAL_FLOAT_MODE_NO_WIDEN(N, B, Y, F) \ + make_float_mode (#N, B, Y, #F, __FILE__, __LINE__, false) static void make_float_mode (const char *name, unsigned int precision, unsigned int bytesize, const char *format, - const char *file, unsigned int line) + const char *file, unsigned int line, + bool normal_widen) { struct mode_data *m = new_mode (MODE_FLOAT, name, file, line); m->bytesize = bytesize; m->precision = precision; m->format = format; + m->normal_widen = normal_widen; } #define DECIMAL_FLOAT_MODE(N, Y, F) \ @@ -871,7 +877,18 @@ create_modes (void) they have the same bytesize; this is the right thing because the precision must always be smaller than the bytesize * BITS_PER_UNIT. We don't have to do anything special to get this done -- an unset - precision shows up as (unsigned int)-1, i.e. UINT_MAX. */ + precision shows up as (unsigned int)-1, i.e. UINT_MAX. + + If a mode is listed as no widen, sort it after the modes that are allowed as + widening types. This is for machine dependent floating point types that we + don't want to automatically promote. + + In particular on the PowerPC there are 2 different explicit 128-bit floating + point types (IBM and IEEE) and long double which coult be either of those + types. We don't want automatic promotion between these types, because there + are values in each type that can't be represented in the other type. On the + PowerPC, other types can be promotoed to long double, but not to the + explicit IEEE or IBM 128-bit types. */ static int cmp_modes (const void *a, const void *b) { @@ -893,6 +910,11 @@ cmp_modes (const void *a, const void *b) else if (m->precision < n->precision) return -1; + if (!m->normal_widen && n->normal_widen) + return 1; + else if (m->normal_widen && !n->normal_widen) + return -1; + if (!m->component && !n->component) { if (m->counter < n->counter) @@ -1541,17 +1563,20 @@ emit_mode_wider (void) { struct mode_data *m2 = 0; - if (m->cl == MODE_INT - || m->cl == MODE_PARTIAL_INT - || m->cl == MODE_FLOAT - || m->cl == MODE_DECIMAL_FLOAT - || m->cl == MODE_COMPLEX_FLOAT - || m->cl == MODE_FRACT - || m->cl == MODE_UFRACT - || m->cl == MODE_ACCUM - || m->cl == MODE_UACCUM) + if (m->normal_widen + && (m->cl == MODE_INT + || m->cl == MODE_PARTIAL_INT + || m->cl == MODE_FLOAT + || m->cl == MODE_DECIMAL_FLOAT + || m->cl == MODE_COMPLEX_FLOAT + || m->cl == MODE_FRACT + || m->cl == MODE_UFRACT + || m->cl == MODE_ACCUM + || m->cl == MODE_UACCUM)) for (m2 = m->wider; m2 && m2 != void_mode; m2 = m2->wider) { + if (!m2->normal_widen) + continue; if (m2->bytesize == m->bytesize && m2->precision == m->precision) continue; @@ -1576,6 +1601,8 @@ emit_mode_wider (void) m2 && m2 != void_mode; m2 = m2->wider) { + if (!m2->normal_widen) + continue; if (m2->bytesize < 2 * m->bytesize) continue; if (m->precision != (unsigned int) -1) diff --git a/gcc/machmode.def b/gcc/machmode.def index 62e2ba10d45..fb10a3af705 100644 --- a/gcc/machmode.def +++ b/gcc/machmode.def @@ -90,6 +90,12 @@ along with GCC; see the file COPYING3. If not see storage, but with only PRECISION significant bits, using floating point format FORMAT. + FRACTIONAL_FLOAT_MODE_NO_WIDEN (MODE, PRECISION, BYTESIZE, FORMAT); + declares MODE to be of class FLOAT, BYTESIZE bytes wide in + storage, but with only PRECISION significant bits, using + floating point format FORMAT. Unlike FRACTIONAL_FLOAT_MODE, + MODE is not listed in the mode_wider and mode_2xwider tables. + DECIMAL_FLOAT_MODE (MODE, BYTESIZE, FORMAT); declares MODE to be of class DECIMAL_FLOAT and BYTESIZE bytes wide. All of the bits of its representation are significant.