public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "cvs-commit at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug tree-optimization/110731] [11/12 Regression] Wrong-code because of wide-int division since r5-424
Date: Sun, 17 Dec 2023 13:55:01 +0000	[thread overview]
Message-ID: <bug-110731-4-bY6ZGGD7TR@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-110731-4@http.gcc.gnu.org/bugzilla/>

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

--- Comment #7 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-11 branch has been updated by Jakub Jelinek
<jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:9e30ca09c01124333dc97e8c2cb704b74d3c7b60

commit r11-11148-g9e30ca09c01124333dc97e8c2cb704b74d3c7b60
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Wed Jul 19 13:48:53 2023 +0200

    wide-int: Fix up wi::divmod_internal [PR110731]

    As the following testcase shows, wi::divmod_internal doesn't handle
    correctly signed division with precision > 64 when the dividend (and likely
    divisor as well) is the type's minimum and the precision isn't divisible
    by 64.

    A few lines above what the patch hunk changes is:
      /* Make the divisor and dividend positive and remember what we
         did.  */
      if (sgn == SIGNED)
        {
          if (wi::neg_p (dividend))
            {
              neg_dividend = -dividend;
              dividend = neg_dividend;
              dividend_neg = true;
            }
          if (wi::neg_p (divisor))
            {
              neg_divisor = -divisor;
              divisor = neg_divisor;
              divisor_neg = true;
            }
        }
    i.e. we negate negative dividend or divisor and remember those.
    But, after we do that, when unpacking those values into b_dividend and
    b_divisor we need to always treat the wide_ints as UNSIGNED,
    because divmod_internal_2 performs an unsigned division only.
    Now, if precision <= 64, we don't reach here at all, earlier code
    handles it.  If dividend or divisor aren't the most negative values,
    the negation clears their most significant bit, so it doesn't really
    matter if we unpack SIGNED or UNSIGNED.  And if precision is multiple
    of HOST_BITS_PER_WIDE_INT, there is no difference in behavior, while
    -0x80000000000000000000000000000000 negates to
    -0x80000000000000000000000000000000 the unpacking of it as SIGNED
    or UNSIGNED works the same.
    In the testcase, we have signed precision 119 and the dividend is
    val = { 0, 0xffc0000000000000 }, len = 2, precision = 119
    both before and after negation.
    Divisor is
    val = { 2 }, len = 1, precision = 119
    But we really want to divide 0x400000000000000000000000000000 by 2
    unsigned and then negate at the end.
    If it is unsigned precision 119 division
    0x400000000000000000000000000000 by 2
    dividend is
    val = { 0, 0xffc0000000000000 }, len = 2, precision = 119
    but as we unpack it UNSIGNED, it is unpacked into
    0, 0, 0, 0x00400000

    The following patch fixes it by always using UNSIGNED unpacking
    because we've already negated negative values at that point if
    sgn == SIGNED and so most negative constants should be treated as
    positive.

    2023-07-19  Jakub Jelinek  <jakub@redhat.com>

            PR tree-optimization/110731
            * wide-int.cc (wi::divmod_internal): Always unpack dividend and
            divisor as UNSIGNED regardless of sgn.

            * gcc.dg/pr110731.c: New test.

    (cherry picked from commit ece799607c841676f4e00c2fea98bbec6976da3f)

  parent reply	other threads:[~2023-12-17 13:55 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-19  7:18 [Bug tree-optimization/110731] New: [11/12/13/14 " jakub at gcc dot gnu.org
2023-07-19  7:19 ` [Bug tree-optimization/110731] " jakub at gcc dot gnu.org
2023-07-19  7:39 ` pinskia at gcc dot gnu.org
2023-07-19  7:56 ` jakub at gcc dot gnu.org
2023-07-19 11:50 ` cvs-commit at gcc dot gnu.org
2023-07-19 12:24 ` cvs-commit at gcc dot gnu.org
2023-07-19 17:56 ` [Bug tree-optimization/110731] [11/12 " jakub at gcc dot gnu.org
2023-12-16  0:37 ` cvs-commit at gcc dot gnu.org
2023-12-17 13:55 ` cvs-commit at gcc dot gnu.org [this message]
2024-06-12 11:58 ` rguenth 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-110731-4-bY6ZGGD7TR@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).