public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug middle-end/67809] New: Empty pointer-chasing loops aren't optimized out
@ 2015-10-01 20:47 matt at godbolt dot org
  2015-10-02  9:29 ` [Bug middle-end/67809] " rguenth at gcc dot gnu.org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: matt at godbolt dot org @ 2015-10-01 20:47 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 67809
           Summary: Empty pointer-chasing loops aren't optimized out
           Product: gcc
           Version: 5.2.0
            Status: UNCONFIRMED
          Severity: minor
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: matt at godbolt dot org
  Target Milestone: ---

The following code:

```
struct Foo {
  Foo *next; 

  void release() {
    Foo *tmp = 0;
    for (Foo *it = next; it; it = tmp) {
      tmp = it->next;
    }
  }
};

void test(Foo &f) { f.release(); }
```

Results in pointer-chasing code when compiled at -O3:

```
test(Foo&):
        mov     rax, QWORD PTR [rdi]
        test    rax, rax
        je      .L1
.L3:
        mov     rax, QWORD PTR [rax]
        test    rax, rax
        jne     .L3
.L1:
        rep ret
```

clang and icc both optimize this to a single ret. e.g. https://goo.gl/saN4XC vs
https://goo.gl/LeUGn0

Would be nice for this loop to go away completely. For context, this was in
code I added to use ASAN_POISON_MEMORY_REGION() around a pooled allocator upon
free of a list (each node was poisoned individually). Without
-fsanitize=address I was expecting the loop to entirely vanish, but the
pointer-chase was still done.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug middle-end/67809] Empty pointer-chasing loops aren't optimized out
  2015-10-01 20:47 [Bug middle-end/67809] New: Empty pointer-chasing loops aren't optimized out matt at godbolt dot org
@ 2015-10-02  9:29 ` rguenth at gcc dot gnu.org
  2015-10-02  9:52 ` glisse at gcc dot gnu.org
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: rguenth at gcc dot gnu.org @ 2015-10-02  9:29 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
We indeed do not have a flag to tell GCC it's ok to remove infinite loops with
no side-effects.  We assume the dereferences will not trap (unless
-fexceptions -fnon-call-exceptions) and GCC happily removes possible traps
so I don't think that would prevent the DCE here.  What prevents DCE is
that the loop might not terminate.  There isn't any "infinite loop is undefined
behavior" thing so clang removing the loop is an invalid transform.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug middle-end/67809] Empty pointer-chasing loops aren't optimized out
  2015-10-01 20:47 [Bug middle-end/67809] New: Empty pointer-chasing loops aren't optimized out matt at godbolt dot org
  2015-10-02  9:29 ` [Bug middle-end/67809] " rguenth at gcc dot gnu.org
@ 2015-10-02  9:52 ` glisse at gcc dot gnu.org
  2021-06-12 12:30 ` gareth@ignition-web.co.uk
  2021-08-28 23:52 ` pinskia at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: glisse at gcc dot gnu.org @ 2015-10-02  9:52 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Marc Glisse <glisse at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #3)
> There isn't any "infinite loop is undefined behavior" thing
> so clang removing the loop is an invalid transform.

In C++ [intro.multithread]

27 The implementation may assume that any thread will eventually do one of the
following:
(27.1) — terminate,
(27.2) — make a call to a library I/O function,
(27.3) — read or modify a volatile object, or
(27.4) — perform a synchronization operation or an atomic operation.
[ Note: This is intended to allow compiler transformations such as removal of
empty loops, even when termination cannot be proven. — end note ]
>From gcc-bugs-return-498600-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org Fri Oct 02 09:58:17 2015
Return-Path: <gcc-bugs-return-498600-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org>
Delivered-To: listarch-gcc-bugs@gcc.gnu.org
Received: (qmail 19590 invoked by alias); 2 Oct 2015 09:58:16 -0000
Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm
Precedence: bulk
List-Id: <gcc-bugs.gcc.gnu.org>
List-Archive: <http://gcc.gnu.org/ml/gcc-bugs/>
List-Post: <mailto:gcc-bugs@gcc.gnu.org>
List-Help: <mailto:gcc-bugs-help@gcc.gnu.org>
Sender: gcc-bugs-owner@gcc.gnu.org
Delivered-To: mailing list gcc-bugs@gcc.gnu.org
Received: (qmail 19529 invoked by uid 48); 2 Oct 2015 09:58:12 -0000
From: "jakub at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug tree-optimization/67815] New: Optimize const1 * copysign (const2, y) into copysign (const1 * const2, y) if const1 > 0 or -copysign (const1 * const2, y) if const1 < 0
Date: Fri, 02 Oct 2015 09:58:00 -0000
X-Bugzilla-Reason: CC
X-Bugzilla-Type: new
X-Bugzilla-Watch-Reason: None
X-Bugzilla-Product: gcc
X-Bugzilla-Component: tree-optimization
X-Bugzilla-Version: 5.2.1
X-Bugzilla-Keywords:
X-Bugzilla-Severity: normal
X-Bugzilla-Who: jakub at gcc dot gnu.org
X-Bugzilla-Status: UNCONFIRMED
X-Bugzilla-Resolution:
X-Bugzilla-Priority: P3
X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org
X-Bugzilla-Target-Milestone: ---
X-Bugzilla-Flags:
X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone
Message-ID: <bug-67815-4@http.gcc.gnu.org/bugzilla/>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/
Auto-Submitted: auto-generated
MIME-Version: 1.0
X-SW-Source: 2015-10/txt/msg00155.txt.bz2
Content-length: 2262

https://gcc.gnu.org/bugzilla/show_bug.cgi?idg815

            Bug ID: 67815
           Summary: Optimize const1 * copysign (const2, y) into copysign
                    (const1 * const2, y) if const1 > 0 or -copysign
                    (const1 * const2, y) if const1 < 0
           Product: gcc
           Version: 5.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jakub at gcc dot gnu.org
  Target Milestone: ---

In 481.wrf, I've noticed several occurrences of (1/12.) * copysign (1.0, var)
and likewise with other constants.  This should be optimizable into just
copysign (1/12., var) (or, say for (-1/12.) * copysign (1.0, var) into
-copysign (1/12., var).
As the expressions are actually x * const1 * copysign (const2, y), the const1
and copysign factors might not appear together, and while reassoc1 pass
sometimes puts them together, sometimes it does not:
  _2051 = __builtin_copysignf (1.0e+0, vel_2000);
...
  _2059 = _2051 * _2058;
  _2060 = _2059 * 1.666666753590106964111328125e-2;
is before reassoc1 and
  _2051 = __builtin_copysignf (1.0e+0, vel_2000);
...
  _2047 = _2051 * 1.666666753590106964111328125e-2;
  _2060 = _2047 * _2058;
is after reassoc1, so in this case reassoc1 worked fine, but in another spot
I see
  _2968 = __builtin_copysignf (1.0e+0, vel_2943);
...
  _2973 = _2968 * _2972;
  _2974 = _2973 * 8.3333335816860198974609375e-2;
before reassoc1 and
  _2968 = __builtin_copysignf (1.0e+0, vel_2943);
...
  _3008 = _2972 * 8.3333335816860198974609375e-2;
  _2974 = _3008 * _2968;
after reassoc1.  Thus, supposedly this should be performed either only in
reassoc, or in reassoc and somewhere else.
Testcase for -Ofast:
float
f0 (float x)
{
  return 7.5 * __builtin_copysignf (1.0, x);
}

double
f1 (double x, double y)
{
  return x * ((1.0/12) * __builtin_copysign (1.0, y));
}

double
f2 (double x, double y)
{
  return (x * (-1.0/12)) * __builtin_copysign (1.0, y);
}

double
f3 (double x, double y, double z)
{
  return (x * z) * ((1.0/12) * __builtin_copysign (4.0, y));
}

double
f4 (double x, double y, double z)
{
  return (x * (-1.0/12)) * z * __builtin_copysign (2.0, y);
}


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug middle-end/67809] Empty pointer-chasing loops aren't optimized out
  2015-10-01 20:47 [Bug middle-end/67809] New: Empty pointer-chasing loops aren't optimized out matt at godbolt dot org
  2015-10-02  9:29 ` [Bug middle-end/67809] " rguenth at gcc dot gnu.org
  2015-10-02  9:52 ` glisse at gcc dot gnu.org
@ 2021-06-12 12:30 ` gareth@ignition-web.co.uk
  2021-08-28 23:52 ` pinskia at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: gareth@ignition-web.co.uk @ 2021-06-12 12:30 UTC (permalink / raw)
  To: gcc-bugs

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

Gareth Lloyd <gareth@ignition-web.co.uk> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |gareth@ignition-web.co.uk

--- Comment #11 from Gareth Lloyd <gareth@ignition-web.co.uk> ---
Looks like as of GCC 10.1 this optimisation exists

This bug can be closed?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug middle-end/67809] Empty pointer-chasing loops aren't optimized out
  2015-10-01 20:47 [Bug middle-end/67809] New: Empty pointer-chasing loops aren't optimized out matt at godbolt dot org
                   ` (2 preceding siblings ...)
  2021-06-12 12:30 ` gareth@ignition-web.co.uk
@ 2021-08-28 23:52 ` pinskia at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-08-28 23:52 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |DUPLICATE

--- Comment #12 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Dup of bug 89713.

We mark loops to be finite when -ffinite-loops is enabled (which is the case
for C++ front-end) and will remove these loops.  r10-1052 implemented part of
this and r10-7522 implemented the other part.

Note there are other loops which are marked finite on the trunk dealing with
recursive calls.

*** This bug has been marked as a duplicate of bug 89713 ***

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-08-28 23:52 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-01 20:47 [Bug middle-end/67809] New: Empty pointer-chasing loops aren't optimized out matt at godbolt dot org
2015-10-02  9:29 ` [Bug middle-end/67809] " rguenth at gcc dot gnu.org
2015-10-02  9:52 ` glisse at gcc dot gnu.org
2021-06-12 12:30 ` gareth@ignition-web.co.uk
2021-08-28 23:52 ` pinskia at gcc dot gnu.org

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).