public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug tree-optimization/97690] New: (cond ? 2 : 0) is not optimized to int(cond) << 1
@ 2020-11-03 10:28 redi at gcc dot gnu.org
  2020-11-03 10:30 ` [Bug tree-optimization/97690] " redi at gcc dot gnu.org
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2020-11-03 10:28 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 97690
           Summary: (cond ? 2 : 0) is not optimized to int(cond) << 1
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
  Target Milestone: ---

enum E { init=0, active=1, done=2 };

int f(bool d)
{
    return d ? done : init;
}

int g(bool d)
{
    return int(d) << 1;
}

The first function is more readable and less fragile (in case the order of bits
is changed) but GCC produces larger code for it.

For x86_64 with -O3:

f(bool):
        xor     eax, eax
        test    dil, dil
        setne   al
        add     eax, eax
        ret
g(bool):
        movzx   eax, dil
        add     eax, eax
        ret

And for x86_64 -Os:

f(bool):
        neg     dil
        sbb     eax, eax
        and     eax, 2
        ret
g(bool):
        movzx   eax, dil
        add     eax, eax
        ret


Clang produces the same code for both functions at all optimization levels:

f(bool):                                  # @f(bool)
        lea     eax, [rdi + rdi]
        ret
g(bool):                                  # @g(bool)
        lea     eax, [rdi + rdi]
        ret

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

* [Bug tree-optimization/97690] (cond ? 2 : 0) is not optimized to int(cond) << 1
  2020-11-03 10:28 [Bug tree-optimization/97690] New: (cond ? 2 : 0) is not optimized to int(cond) << 1 redi at gcc dot gnu.org
@ 2020-11-03 10:30 ` redi at gcc dot gnu.org
  2020-11-03 10:37 ` redi at gcc dot gnu.org
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2020-11-03 10:30 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
It seems to be target-independent. For aarch64, -O3 and -Os both give:

f(bool):
        tst     w0, 255
        cset    w0, ne
        lsl     w0, w0, 1
        ret
g(bool):
        ubfiz   w0, w0, 1, 8
        ret


And avr -Os is horrible:

__zero_reg__ = 1
f(bool):
        cpse r24,__zero_reg__
        rjmp .L3
        ldi r25,0
        ldi r24,0
        ret
.L3:
        ldi r24,lo8(2)
        ldi r25,0
        ret
g(bool):
        ldi r25,0
        lsl r24
        rol r25
ret

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

* [Bug tree-optimization/97690] (cond ? 2 : 0) is not optimized to int(cond) << 1
  2020-11-03 10:28 [Bug tree-optimization/97690] New: (cond ? 2 : 0) is not optimized to int(cond) << 1 redi at gcc dot gnu.org
  2020-11-03 10:30 ` [Bug tree-optimization/97690] " redi at gcc dot gnu.org
@ 2020-11-03 10:37 ` redi at gcc dot gnu.org
  2020-11-03 12:55 ` rguenth at gcc dot gnu.org
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2020-11-03 10:37 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
More generally, Clang seems to reliably turn

cond ? (2<<N) : 0

into:

int(bool(cond)) << N


Including when using immediates or constants in places of 2<<N and 0.

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

* [Bug tree-optimization/97690] (cond ? 2 : 0) is not optimized to int(cond) << 1
  2020-11-03 10:28 [Bug tree-optimization/97690] New: (cond ? 2 : 0) is not optimized to int(cond) << 1 redi at gcc dot gnu.org
  2020-11-03 10:30 ` [Bug tree-optimization/97690] " redi at gcc dot gnu.org
  2020-11-03 10:37 ` redi at gcc dot gnu.org
@ 2020-11-03 12:55 ` rguenth at gcc dot gnu.org
  2020-11-03 17:32 ` jakub at gcc dot gnu.org
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-11-03 12:55 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2020-11-03
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
IMHO sth reasonable to do for phiopt which already value-replaces other
forms of true/false so it shouldn't be too hard to add.

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

* [Bug tree-optimization/97690] (cond ? 2 : 0) is not optimized to int(cond) << 1
  2020-11-03 10:28 [Bug tree-optimization/97690] New: (cond ? 2 : 0) is not optimized to int(cond) << 1 redi at gcc dot gnu.org
                   ` (2 preceding siblings ...)
  2020-11-03 12:55 ` rguenth at gcc dot gnu.org
@ 2020-11-03 17:32 ` jakub at gcc dot gnu.org
  2020-11-04 11:15 ` cvs-commit at gcc dot gnu.org
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-11-03 17:32 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
           Assignee|unassigned at gcc dot gnu.org      |jakub at gcc dot gnu.org

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Created attachment 49498
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49498&action=edit
gcc11-pr97690.patch

This seems to work (though untested so far except for phi-opt*.c tests).

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

* [Bug tree-optimization/97690] (cond ? 2 : 0) is not optimized to int(cond) << 1
  2020-11-03 10:28 [Bug tree-optimization/97690] New: (cond ? 2 : 0) is not optimized to int(cond) << 1 redi at gcc dot gnu.org
                   ` (3 preceding siblings ...)
  2020-11-03 17:32 ` jakub at gcc dot gnu.org
@ 2020-11-04 11:15 ` cvs-commit at gcc dot gnu.org
  2021-05-24  7:12 ` pinskia at gcc dot gnu.org
  2021-06-01 20:50 ` pinskia at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2020-11-04 11:15 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:3e190757fa332d327bee27495f37beb01155cfab

commit r11-4717-g3e190757fa332d327bee27495f37beb01155cfab
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Wed Nov 4 11:55:29 2020 +0100

    phiopt: Optimize x ? 1024 : 0 to (int) x << 10 [PR97690]

    The following patch generalizes the x ? 1 : 0 -> (int) x optimization
    to handle also left shifts by constant.

    During x86_64-linux and i686-linux bootstraps + regtests it triggered
    in 1514 unique non-LTO -m64 cases (sort -u on log mentioning
    filename, function name and shift count) and 1866 -m32 cases.

    Unfortunately, the patch regresses (before the tests have been adjusted):
    +FAIL: gcc.dg/tree-ssa/ssa-ccp-11.c scan-tree-dump-times optimized "if " 0
    +FAIL: gcc.dg/vect/bb-slp-pattern-2.c -flto -ffat-lto-objects 
scan-tree-dump-times slp1 "optimized: basic block" 1
    +FAIL: gcc.dg/vect/bb-slp-pattern-2.c scan-tree-dump-times slp1 "optimized:
basic block" 1
    and in both cases it actually results in worse code.

    > > We'd need some optimization that would go through all PHI edges and
    > > compute if some use of the phi results don't actually compute a
constant
    > > across all the PHI edges - 1 & 0 and 0 & 1 is always 0.

    > PRE should do this, IMHO only optimizing it at -O2 is fine.

    > > Similarly, in the slp vectorization test there is:
    > >      a[0] = b[0] ? 1 : 7;

    > note this, carefully avoiding the already "optimized" b[0] ? 1 : 0 ...

    > So the option is to put : 7 in the 2, 4 an 8 case as well.  The testcase
    > wasn't added for any real-world case but is artificial I guess for
    > COND_EXPR handling of invariants.

    > But yeah, for things like SLP it means we eventually have to
    > implement reverse transforms for all of this to make the lanes
    > matching.  But that's true anyway for things like x + 1 vs. x + 0
    > or x / 3 vs. x / 2 or other simplifications we do.

    2020-11-04  Jakub Jelinek  <jakub@redhat.com>

            PR tree-optimization/97690
            * tree-ssa-phiopt.c (conditional_replacement): Also optimize
            cond ? pow2p_cst : 0 as ((type) cond) << cst.

            * gcc.dg/tree-ssa/phi-opt-22.c: New test.
            * gcc.dg/tree-ssa/ssa-ccp-11.c: Use -O2 instead of -O1.
            * gcc.dg/vect/bb-slp-pattern-2.c (foo): Use ? 2 : 7, ? 4 : 7 and
            ? 8 : 7 instead of ? 2 : 0, ? 4 : 0, ? 8 : 0.

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

* [Bug tree-optimization/97690] (cond ? 2 : 0) is not optimized to int(cond) << 1
  2020-11-03 10:28 [Bug tree-optimization/97690] New: (cond ? 2 : 0) is not optimized to int(cond) << 1 redi at gcc dot gnu.org
                   ` (4 preceding siblings ...)
  2020-11-04 11:15 ` cvs-commit at gcc dot gnu.org
@ 2021-05-24  7:12 ` pinskia at gcc dot gnu.org
  2021-06-01 20:50 ` pinskia at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-05-24  7:12 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |pawel_sikora at zoho dot com

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

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

* [Bug tree-optimization/97690] (cond ? 2 : 0) is not optimized to int(cond) << 1
  2020-11-03 10:28 [Bug tree-optimization/97690] New: (cond ? 2 : 0) is not optimized to int(cond) << 1 redi at gcc dot gnu.org
                   ` (5 preceding siblings ...)
  2021-05-24  7:12 ` pinskia at gcc dot gnu.org
@ 2021-06-01 20:50 ` pinskia at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-06-01 20:50 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
         Resolution|---                         |FIXED
   Target Milestone|---                         |11.0

--- Comment #7 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Fixed for GCC 11.

GCC 12 moves the simplifications to match.pd too.

So closing.

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

end of thread, other threads:[~2021-06-01 20:50 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-03 10:28 [Bug tree-optimization/97690] New: (cond ? 2 : 0) is not optimized to int(cond) << 1 redi at gcc dot gnu.org
2020-11-03 10:30 ` [Bug tree-optimization/97690] " redi at gcc dot gnu.org
2020-11-03 10:37 ` redi at gcc dot gnu.org
2020-11-03 12:55 ` rguenth at gcc dot gnu.org
2020-11-03 17:32 ` jakub at gcc dot gnu.org
2020-11-04 11:15 ` cvs-commit at gcc dot gnu.org
2021-05-24  7:12 ` pinskia at gcc dot gnu.org
2021-06-01 20:50 ` 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).