public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "jakub at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug tree-optimization/104196] [12 Regression] wrong code at -O2 and above on x86_64-linux-gnu
Date: Mon, 24 Jan 2022 16:12:48 +0000	[thread overview]
Message-ID: <bug-104196-4-LKQelDIRPN@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-104196-4@http.gcc.gnu.org/bugzilla/>

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

--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, to me this doesn't look like a recent reassoc1 regression, but rather
something that been there since
~ r0-119920-gd578e863b08e64789f767c95f85acd10dc477bdf

The inter-bb range optimization pass uses no_side_effect_bb as a test for the
bbs in between, which makes sure that no statements have side-effects, there
are only gimple assignments except for the last GIMPLE_COND and those
statements can't trap and their lhs is consumed within the same bb.

  if (a.1_1 >= 0)
    goto <bb 5>; [59.00%]
  else
    goto <bb 4>; [41.00%]

  <bb 4> [local count: 440234144]:
  _3 = -2147483647 - a.1_1;
  _9 = a.1_1 != -2147479551;
  _4 = _3 == 1;
  _8 = _4 | _9;
  if (_8 != 0)
    goto <bb 5>; [34.51%]
  else
    goto <bb 3>; [65.49%]

is then treated as if ((a.1_1 >= 0) | (-2147483647 - a.1_1 == 1) | (a.1_1 !=
-2147479551)) goto bb5; else goto bb3;
and in there we optimize from there the (a.1_1 >= 0) | (a.1_1 != -2147479551)
part of it into (a.1_1 != -2147479551).  That is all fine, but we have chosen
to put the merged condition into the place of the old _9 test and make the
the a.1_1 >= 0 test (which has been replaced by false).  Usually that doesn't
really matter where we stick it, when merging multiple "ops" into one, one
simply wins (that is the range in update_range_test) and the other(s) are
marked
as true/false (otherrange ... otherrange + count - 1).
The problem above is that the _3 = -2147483647 - a.1_1; stmt is done in
undefined overflow type and thus can trigger UB where there wasn't one before
for certain values.

One possibility to fix this would be to punt on statements like that in
no_side_effect_bb (e.g. the normal way to encode a range is using unsigned
arithmetics).  But I'd be afraid we could easily regress on what the
optimization can handle.

Another possibility is try to be smarter in update_range_test.  Instead of
always picking range->idx as the winner and otherrange*->idx as the stmts
replaced by false or true, perhaps we should try to be smarter, go through them
all first and pick the one from the first bb (one dominating all the other ops)
and if the merge is successful, swap range->idx with the most dominating
otherrange->idx.

So, instead of the problematic
  <bb 2> [local count: 118111598]:

  <bb 3> [local count: 1073741824]:
  a.1_1 = a;
  _3 = -2147483647 - a.1_1;
  _10 = a.1_1 != -2147479551;
  _9 = a.1_1 != -2147479551;
  _4 = _3 == 1;
  _2 = _4 | _10;
  if (_2 != 0)
    goto <bb 4>; [34.51%]
  else
    goto <bb 3>; [65.49%]
we'd get
  a.1_1 = a;
  if (a.1_1 != -2147479551)
    goto <bb 5>; [59.00%]
  else
    goto <bb 4>; [41.00%]

  <bb 4> [local count: 440234144]:
  _3 = -2147483647 - a.1_1;
  _9 = 0;
  _4 = _3 == 1;
  _8 = _4 | _9;
  if (_8 != 0)
    goto <bb 5>; [34.51%]
  else
    goto <bb 3>; [65.49%]


Another question but that is GCC 13 material is why we don't optimize
int
foo (int x)
{
  return -2147483647 - x <= 0;
}
into:
  return x >= -2147483647
during GIMPLE (we optimize it during expansion it seems).

  parent reply	other threads:[~2022-01-24 16:12 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-24  0:01 [Bug c/104196] New: " cnsun at uwaterloo dot ca
2022-01-24  0:17 ` [Bug middle-end/104196] " jakub at gcc dot gnu.org
2022-01-24  0:17 ` [Bug tree-optimization/104196] [12 Regression] " jakub at gcc dot gnu.org
2022-01-24  0:37 ` pinskia at gcc dot gnu.org
2022-01-24  1:52 ` pinskia at gcc dot gnu.org
2022-01-24  2:00 ` pinskia at gcc dot gnu.org
2022-01-24  2:17 ` pinskia at gcc dot gnu.org
2022-01-24  2:19 ` pinskia at gcc dot gnu.org
2022-01-24  5:58 ` belyshev at depni dot sinp.msu.ru
2022-01-24 16:12 ` jakub at gcc dot gnu.org [this message]
2022-01-26 10:52 ` jakub at gcc dot gnu.org
2022-01-26 14:07 ` jakub at gcc dot gnu.org
2022-01-27  9:47 ` cvs-commit at gcc dot gnu.org
2022-01-27 10:20 ` jakub 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-104196-4-LKQelDIRPN@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).