public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Michael Meissner <meissner@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/meissner/heads/work107)] Improve PowerPC 128-bit floating point types. Date: Wed, 25 Jan 2023 02:59:49 +0000 (GMT) [thread overview] Message-ID: <20230125025949.C48A03858413@sourceware.org> (raw) https://gcc.gnu.org/g:2addd92c25c5b5cc9f223a9cb377ccc6aae52c99 commit 2addd92c25c5b5cc9f223a9cb377ccc6aae52c99 Author: Michael Meissner <meissner@linux.ibm.com> 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 <meissner@linux.ibm.com> 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<INT_N> 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, "<unknown>", 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.
reply other threads:[~2023-01-25 2:59 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20230125025949.C48A03858413@sourceware.org \ --to=meissner@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).