public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/109112] New: [missed optimization] odd behaviour with [[assume(...)]] and member variables
@ 2023-03-13 18:49 ivan.lazaric.gcc at gmail dot com
  2023-03-13 18:54 ` [Bug c++/109112] " jakub at gcc dot gnu.org
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: ivan.lazaric.gcc at gmail dot com @ 2023-03-13 18:49 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 109112
           Summary: [missed optimization] odd behaviour with
                    [[assume(...)]] and member variables
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ivan.lazaric.gcc at gmail dot com
  Target Milestone: ---

Everything is built with flags: -std=c++23 -O3

[[assume(...)]] doesn't seem to work quite as well when dealing with member
variables.

First version of `fn`:

void do_something();
void fn(bool x){
    [[assume(!x)]];
    if (x) do_something();
}

`fn` compiles into nothing:
fn(bool):
  ret

Second version of `fn`, wrapping the `bool` argument in a simple struct:

struct S { bool x; };
void do_something();
void fn(S s){
    [[assume(!s.x)]];
    if (s.x) do_something();
}

This no longer compiles into just `ret`:
fn(S):
        test    dil, dil
        jne     .L5
        ret
.L5:
        jmp     do_something()

Expected behaviour was for `fn(S)` to reduce to just `ret`

Godbolt link with the examples: https://godbolt.org/z/nreM4Y6dW

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

* [Bug c++/109112] [missed optimization] odd behaviour with [[assume(...)]] and member variables
  2023-03-13 18:49 [Bug c++/109112] New: [missed optimization] odd behaviour with [[assume(...)]] and member variables ivan.lazaric.gcc at gmail dot com
@ 2023-03-13 18:54 ` jakub at gcc dot gnu.org
  2023-03-13 18:57 ` [Bug tree-optimization/109112] " pinskia at gcc dot gnu.org
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-03-13 18:54 UTC (permalink / raw)
  To: gcc-bugs

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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
There is nothing odd on it.  The extra optimization information assume provides
is right now used solely by value range propagation and that works only on
scalars.  For anything else, the assumptions are noted but for now nothing
takes advantage of them.  And it will take a while before that changes. 
Assumptions provide optimization hints, the compiler isn't required to make use
of them.  There will always be assumptions which compiler won't be able to do
anything with them.

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

* [Bug tree-optimization/109112] [missed optimization] odd behaviour with [[assume(...)]] and member variables
  2023-03-13 18:49 [Bug c++/109112] New: [missed optimization] odd behaviour with [[assume(...)]] and member variables ivan.lazaric.gcc at gmail dot com
  2023-03-13 18:54 ` [Bug c++/109112] " jakub at gcc dot gnu.org
@ 2023-03-13 18:57 ` pinskia at gcc dot gnu.org
  2023-03-13 18:58 ` [Bug tree-optimization/109112] [[assume(...)]] is not taken into account for structs pinskia at gcc dot gnu.org
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-03-13 18:57 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                URL|https://godbolt.org/z/nreM4 |
                   |Y6dW                        |
          Component|c++                         |tree-optimization
           Keywords|                            |missed-optimization
           Severity|normal                      |enhancement

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
https://godbolt.org/z/nreM4Y6dW

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

* [Bug tree-optimization/109112] [[assume(...)]] is not taken into account for structs
  2023-03-13 18:49 [Bug c++/109112] New: [missed optimization] odd behaviour with [[assume(...)]] and member variables ivan.lazaric.gcc at gmail dot com
  2023-03-13 18:54 ` [Bug c++/109112] " jakub at gcc dot gnu.org
  2023-03-13 18:57 ` [Bug tree-optimization/109112] " pinskia at gcc dot gnu.org
@ 2023-03-13 18:58 ` pinskia at gcc dot gnu.org
  2023-03-13 18:59 ` jakub at gcc dot gnu.org
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-03-13 18:58 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
I also suspect this is a dup of bug 109045 really.

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

* [Bug tree-optimization/109112] [[assume(...)]] is not taken into account for structs
  2023-03-13 18:49 [Bug c++/109112] New: [missed optimization] odd behaviour with [[assume(...)]] and member variables ivan.lazaric.gcc at gmail dot com
                   ` (2 preceding siblings ...)
  2023-03-13 18:58 ` [Bug tree-optimization/109112] [[assume(...)]] is not taken into account for structs pinskia at gcc dot gnu.org
@ 2023-03-13 18:59 ` jakub at gcc dot gnu.org
  2023-07-13 15:01 ` jason at gcc dot gnu.org
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-03-13 18:59 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
One way to improve this case would be to teach IPA SRA/CP etc. to perform some
optimizations on the .ASSUME ifn calls and their corresponding functions, in
this case if SRA would turn the argument from aggregate to scalar.

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

* [Bug tree-optimization/109112] [[assume(...)]] is not taken into account for structs
  2023-03-13 18:49 [Bug c++/109112] New: [missed optimization] odd behaviour with [[assume(...)]] and member variables ivan.lazaric.gcc at gmail dot com
                   ` (3 preceding siblings ...)
  2023-03-13 18:59 ` jakub at gcc dot gnu.org
@ 2023-07-13 15:01 ` jason at gcc dot gnu.org
  2023-07-13 15:06 ` jakub at gcc dot gnu.org
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: jason at gcc dot gnu.org @ 2023-07-13 15:01 UTC (permalink / raw)
  To: gcc-bugs

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

Jason Merrill <jason at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jason at gcc dot gnu.org
   Last reconfirmed|                            |2023-07-13
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1

--- Comment #5 from Jason Merrill <jason at gcc dot gnu.org> ---
Note that the __builtin_unreachable variant is optimized as expected:

struct S { bool x; };
void do_something();
void fn(S s) {
  if (s.x) __builtin_unreachable ();
  if (s.x) do_something();
}

It's unfortunate that [[assume (x)]] is currently so much less useful than if
(!x) __builtin_unreachable(), which expresses almost the same thing.

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

* [Bug tree-optimization/109112] [[assume(...)]] is not taken into account for structs
  2023-03-13 18:49 [Bug c++/109112] New: [missed optimization] odd behaviour with [[assume(...)]] and member variables ivan.lazaric.gcc at gmail dot com
                   ` (4 preceding siblings ...)
  2023-07-13 15:01 ` jason at gcc dot gnu.org
@ 2023-07-13 15:06 ` jakub at gcc dot gnu.org
  2023-07-13 21:00 ` jason at gcc dot gnu.org
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-07-13 15:06 UTC (permalink / raw)
  To: gcc-bugs

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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jamborm at gcc dot gnu.org

--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
CCing Martin, I don't have sufficient experience with IPA SRA nor IPA CP to be
able to handle this.

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

* [Bug tree-optimization/109112] [[assume(...)]] is not taken into account for structs
  2023-03-13 18:49 [Bug c++/109112] New: [missed optimization] odd behaviour with [[assume(...)]] and member variables ivan.lazaric.gcc at gmail dot com
                   ` (5 preceding siblings ...)
  2023-07-13 15:06 ` jakub at gcc dot gnu.org
@ 2023-07-13 21:00 ` jason at gcc dot gnu.org
  2023-07-14 12:48 ` jakub at gcc dot gnu.org
  2024-01-21  3:00 ` [Bug ipa/109112] " pinskia at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: jason at gcc dot gnu.org @ 2023-07-13 21:00 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #7 from Jason Merrill <jason at gcc dot gnu.org> ---
In an email thread Jakub wrote:
----
Only the simplest assumptions in [[assume(cond)]] where there clearly aren't
any
side-effects no risks of them are lowered to if (!cond) __builtin_unreachable
();
in the IL, anything else goes into the condition being outlined in a
separate artificial function and an internal function recording the
assumption in the IL.
The optimizers then can optimize both the artificial function and the
caller.
The missed optimization thing is that currently only the value range
propagation is able to take advantage of the assumptions, and VRP
is only able to deal with scalars.
We have interprocedural optimizations like IPA scalar replacement of
aggregates etc., where we can optimize passing aggregates at function
boundaries to passing just some scalars from them if the rest isn't needed
etc., but because the assumptions aren't normal calls they'd need tweaks to
be able to optimize the assumptions too so that VRP could take advantage of
those.
----

Why don't the existing optimizations work on the artificial function the same
as any other function?  i.e. like

struct S { bool x; };
void do_something();
inline void assumption_1 (const S& s) noexcept {
  if (s.x) __builtin_unreachable ();
}
void fn(S s) {
  assumption_1 (s);
  if (s.x) do_something();
}

which is also optimized as expected.

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

* [Bug tree-optimization/109112] [[assume(...)]] is not taken into account for structs
  2023-03-13 18:49 [Bug c++/109112] New: [missed optimization] odd behaviour with [[assume(...)]] and member variables ivan.lazaric.gcc at gmail dot com
                   ` (6 preceding siblings ...)
  2023-07-13 21:00 ` jason at gcc dot gnu.org
@ 2023-07-14 12:48 ` jakub at gcc dot gnu.org
  2024-01-21  3:00 ` [Bug ipa/109112] " pinskia at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-07-14 12:48 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Jason Merrill from comment #7)
> Why don't the existing optimizations work on the artificial function the
> same as any other function?  i.e. like
> 
> struct S { bool x; };
> void do_something();
> inline void assumption_1 (const S& s) noexcept {
>   if (s.x) __builtin_unreachable ();
> }
> void fn(S s) {
>   assumption_1 (s);
>   if (s.x) do_something();
> }
> 
> which is also optimized as expected.

Because the assumptions have different representation in the IL.
While normal calls look like:
  ret = foo (arg1, arg2, arg3);
and we can inline those etc., because the assumptions potentially contain
side-effects which shouldn't be evaluated and therefore should e.g. not be
inlined nor assumed that they are actually called, the representation is like:
  .ASSUME (&foo, arg1, arg2, arg3);
where foo is that artificial assumption function which takes arg1, arg2, arg3.
The above behaves like if (!foo (arg1, arg2, arg3)) __builtin_unreachable ();
except that the function actually isn't called (nor emitted into assembly
etc.).
The assumption is if this function would be called and returned false at this
spot,
it would be UB.
So, VRP walks the assumption function (after optimizations are performed on it,
e.g. inlining into those and various other optimizations) backwards from the
return value starting with [1, 1] and from that derives ranges for the
arguments.

Similarly to how for functions which aren't inlined but can be e.g. cloned it
is essential to get IPA SRA and IPA CP etc. optimizations to tweak the
arguments of functions (scalarize them, remove unneeded ones, replace others),
it is needed
that we optimize the assumptions similarly.  The assumption functions should be
always static and often will have a single reference (unless inlined multiple
times / loop unrolled), so it is just fine to tweak them, just those
optimizations will need
to special case the IFN_ASSUME internal calls and treat
.ASSUME (&foo, arg1, arg2, arg3);
more like
foo (arg1, arg2, arg3);
(i.e. off by one argument and treat it as if there was a call edge from the
.ASSUME
caller to foo.

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

* [Bug ipa/109112] [[assume(...)]] is not taken into account for structs
  2023-03-13 18:49 [Bug c++/109112] New: [missed optimization] odd behaviour with [[assume(...)]] and member variables ivan.lazaric.gcc at gmail dot com
                   ` (7 preceding siblings ...)
  2023-07-14 12:48 ` jakub at gcc dot gnu.org
@ 2024-01-21  3:00 ` pinskia at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-01-21  3:00 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |eric-bugs at omnifarious dot org

--- Comment #9 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
*** Bug 113527 has been marked as a duplicate of this bug. ***

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

end of thread, other threads:[~2024-01-21  3:00 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-13 18:49 [Bug c++/109112] New: [missed optimization] odd behaviour with [[assume(...)]] and member variables ivan.lazaric.gcc at gmail dot com
2023-03-13 18:54 ` [Bug c++/109112] " jakub at gcc dot gnu.org
2023-03-13 18:57 ` [Bug tree-optimization/109112] " pinskia at gcc dot gnu.org
2023-03-13 18:58 ` [Bug tree-optimization/109112] [[assume(...)]] is not taken into account for structs pinskia at gcc dot gnu.org
2023-03-13 18:59 ` jakub at gcc dot gnu.org
2023-07-13 15:01 ` jason at gcc dot gnu.org
2023-07-13 15:06 ` jakub at gcc dot gnu.org
2023-07-13 21:00 ` jason at gcc dot gnu.org
2023-07-14 12:48 ` jakub at gcc dot gnu.org
2024-01-21  3:00 ` [Bug ipa/109112] " 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).