public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "rguenth at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug c++/109359] [12/13 Regression] Compile-time rounding of double literal to float is incorrect with -frounding-math
Date: Fri, 14 Apr 2023 10:08:37 +0000	[thread overview]
Message-ID: <bug-109359-4-Gg0pUZb1iy@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-109359-4@http.gcc.gnu.org/bugzilla/>

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109359

--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
output_constant gets called with

{(float) 1.91399999999999990279997419406754488591104745864868164062e-3, (float)
6.305389999999999606217215841752476990222930908203125e-1}

it then eventually does

  /* Eliminate any conversions since we'll be outputting the underlying
     constant.  */
  while (CONVERT_EXPR_P (exp)
         || TREE_CODE (exp) == NON_LVALUE_EXPR
         || TREE_CODE (exp) == VIEW_CONVERT_EXPR)
    {
      HOST_WIDE_INT type_size = int_size_in_bytes (TREE_TYPE (exp));
      HOST_WIDE_INT op_size = int_size_in_bytes (TREE_TYPE (TREE_OPERAND (exp,
0)));

      /* Make sure eliminating the conversion is really a no-op, except with
         VIEW_CONVERT_EXPRs to allow for wild Ada unchecked conversions and
         union types to allow for Ada unchecked unions.  */
      if (type_size > op_size
          && TREE_CODE (exp) != VIEW_CONVERT_EXPR
          && TREE_CODE (TREE_TYPE (exp)) != UNION_TYPE)
        /* Keep the conversion. */
        break;
      else
        exp = TREE_OPERAND (exp, 0);
    }

where we strip conversions with type_size < op_size (aka float from double).
For float conversions not sure if just keying on type size is good enough
though (ibm double double vs long double 128 for example).

Fixing that "improves" the behavior to

t.ii:1:34: error: initializer for floating value is not a floating constant
    1 | float xs[] = {0.001914, 0.630539};
      |                                  ^
t.ii:1:34: error: initializer for floating value is not a floating constant

aka from wrong-code to rejects-valid.

diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index cd0cd88321c..e6ab581dc5f 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -5202,7 +5202,7 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size,
unsigned int align,
       /* Make sure eliminating the conversion is really a no-op, except with
         VIEW_CONVERT_EXPRs to allow for wild Ada unchecked conversions and
         union types to allow for Ada unchecked unions.  */
-      if (type_size > op_size
+      if (type_size != op_size
          && TREE_CODE (exp) != VIEW_CONVERT_EXPR
          && TREE_CODE (TREE_TYPE (exp)) != UNION_TYPE)
        /* Keep the conversion. */

note that for integral and pointer types we do

      cst = expand_expr (exp, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
      if (reverse)
        cst = flip_storage_order (TYPE_MODE (TREE_TYPE (exp)), cst);
      if (!assemble_integer (cst, MIN (size, thissize), align, 0))
        error ("initializer for integer/fixed-point value is too complicated");

so we handle "narrowing" in a weird way.  So in case FEs leave around
nop-casts the following should be safer

diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index cd0cd88321c..81f7288449c 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -5196,13 +5196,17 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size,
unsigned int align,
         || TREE_CODE (exp) == NON_LVALUE_EXPR
         || TREE_CODE (exp) == VIEW_CONVERT_EXPR)
     {
-      HOST_WIDE_INT type_size = int_size_in_bytes (TREE_TYPE (exp));
-      HOST_WIDE_INT op_size = int_size_in_bytes (TREE_TYPE (TREE_OPERAND (exp,
0)));
+      tree type = TREE_TYPE (exp);
+      tree op_type = TREE_TYPE (TREE_OPERAND (exp, 0));
+      HOST_WIDE_INT type_size = int_size_in_bytes (type);
+      HOST_WIDE_INT op_size = int_size_in_bytes (op_type);

       /* Make sure eliminating the conversion is really a no-op, except with
         VIEW_CONVERT_EXPRs to allow for wild Ada unchecked conversions and
         union types to allow for Ada unchecked unions.  */
-      if (type_size > op_size
+      if ((type_size > op_size
+          || (TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (op_type)
+              && FLOAT_TYPE_P (type)))
          && TREE_CODE (exp) != VIEW_CONVERT_EXPR
          && TREE_CODE (TREE_TYPE (exp)) != UNION_TYPE)
        /* Keep the conversion. */

The real fix is of course in the frontend, the above is just a safety net.

  parent reply	other threads:[~2023-04-14 10:08 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-31 12:33 [Bug c++/109359] New: " rcopley at gmail dot com
2023-03-31 13:23 ` [Bug c++/109359] [12/13 Regression] " rguenth at gcc dot gnu.org
2023-03-31 13:36 ` jakub at gcc dot gnu.org
2023-03-31 14:23 ` jakub at gcc dot gnu.org
2023-04-14  9:49 ` rguenth at gcc dot gnu.org
2023-04-14 10:03 ` jakub at gcc dot gnu.org
2023-04-14 10:08 ` rguenth at gcc dot gnu.org [this message]
2023-04-14 10:12 ` jakub at gcc dot gnu.org
2023-05-08 12:26 ` [Bug c++/109359] [12/13/14 " rguenth at gcc dot gnu.org
2024-02-05 18:24 ` jason at gcc dot gnu.org
2024-02-05 18:34 ` [Bug c++/109359] [12/13 " jason at gcc dot gnu.org
2024-02-05 18:47 ` jakub at gcc dot gnu.org
2024-02-05 18:55 ` jason at gcc dot gnu.org
2024-02-05 21:35 ` cvs-commit at gcc dot gnu.org
2024-02-05 22:25 ` cvs-commit at gcc dot gnu.org
2024-02-05 22:25 ` cvs-commit at gcc dot gnu.org
2024-02-05 22:26 ` jason at gcc dot gnu.org

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=bug-109359-4-Gg0pUZb1iy@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@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: link
Be 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).