public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug middle-end/101955] New: (signed<<31)>>31 should become -(signed&1)
@ 2021-08-18  5:47 pinskia at gcc dot gnu.org
  2021-08-18  5:48 ` [Bug middle-end/101955] " pinskia at gcc dot gnu.org
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-08-18  5:47 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 101955
           Summary: (signed<<31)>>31 should become -(signed&1)
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: enhancement
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pinskia at gcc dot gnu.org
  Target Milestone: ---

Take:
int f(int b)
{
    return (((b)<<31)>>31);
}
int f1(int b)
{
    return -(b&1);
}
These two should produce the same code.

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

* [Bug middle-end/101955] (signed<<31)>>31 should become -(signed&1)
  2021-08-18  5:47 [Bug middle-end/101955] New: (signed<<31)>>31 should become -(signed&1) pinskia at gcc dot gnu.org
@ 2021-08-18  5:48 ` pinskia at gcc dot gnu.org
  2021-08-18  6:49 ` rguenth at gcc dot gnu.org
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-08-18  5:48 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=97743

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
I should have said I found this while looking at 97743.

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

* [Bug middle-end/101955] (signed<<31)>>31 should become -(signed&1)
  2021-08-18  5:47 [Bug middle-end/101955] New: (signed<<31)>>31 should become -(signed&1) pinskia at gcc dot gnu.org
  2021-08-18  5:48 ` [Bug middle-end/101955] " pinskia at gcc dot gnu.org
@ 2021-08-18  6:49 ` rguenth at gcc dot gnu.org
  2021-08-18 15:51 ` schwab@linux-m68k.org
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: rguenth at gcc dot gnu.org @ 2021-08-18  6:49 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2021-08-18
           Keywords|                            |easyhack
             Status|UNCONFIRMED                 |NEW

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

* [Bug middle-end/101955] (signed<<31)>>31 should become -(signed&1)
  2021-08-18  5:47 [Bug middle-end/101955] New: (signed<<31)>>31 should become -(signed&1) pinskia at gcc dot gnu.org
  2021-08-18  5:48 ` [Bug middle-end/101955] " pinskia at gcc dot gnu.org
  2021-08-18  6:49 ` rguenth at gcc dot gnu.org
@ 2021-08-18 15:51 ` schwab@linux-m68k.org
  2021-08-18 17:51 ` pinskia at gcc dot gnu.org
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: schwab@linux-m68k.org @ 2021-08-18 15:51 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Andreas Schwab <schwab@linux-m68k.org> ---
If you want to be agressive you can optimize f to return 0.

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

* [Bug middle-end/101955] (signed<<31)>>31 should become -(signed&1)
  2021-08-18  5:47 [Bug middle-end/101955] New: (signed<<31)>>31 should become -(signed&1) pinskia at gcc dot gnu.org
                   ` (2 preceding siblings ...)
  2021-08-18 15:51 ` schwab@linux-m68k.org
@ 2021-08-18 17:51 ` pinskia at gcc dot gnu.org
  2021-08-18 19:22 ` jakub at gcc dot gnu.org
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-08-18 17:51 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
This is also the sign extend for loading one bit.
That is take
struct g
{
    int a:1;
    int b0:1;
    int b1:1;
    int b2:1;
    int b:1;
};

int h(struct g *a)
{
    return a->a;
}

Currently on x86_64 -O2 GCC does:

        movzbl  (%rdi), %eax
        sall    $31, %eax
        sarl    $31, %eax
        ret

While we should do (and llvm does):
        movzbl  (%rdi), %eax
        andl    $1, %eax
        negl    %eax
        retq

This helps really on targets like avr more than any really.

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

* [Bug middle-end/101955] (signed<<31)>>31 should become -(signed&1)
  2021-08-18  5:47 [Bug middle-end/101955] New: (signed<<31)>>31 should become -(signed&1) pinskia at gcc dot gnu.org
                   ` (3 preceding siblings ...)
  2021-08-18 17:51 ` pinskia at gcc dot gnu.org
@ 2021-08-18 19:22 ` jakub at gcc dot gnu.org
  2021-11-11  0:21 ` navidrahimi at microsoft dot com
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: jakub at gcc dot gnu.org @ 2021-08-18 19:22 UTC (permalink / raw)
  To: gcc-bugs

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

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

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

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Andreas Schwab from comment #2)
> If you want to be agressive you can optimize f to return 0.

In the middle-end?  No, whether it is well defined or undefined depends heavily
on the C/C++ version.
At least ubsan flags it only with C99..C2X, not in C89 nor any C++ versions for
b  1.
For b -1 flaged in C99..C2X and C++11..C++17. C89, C++98 and C++20..C++23
accept that.
Similarly for b > 1, flagged in C99..C2x and C++11..C++17 only.

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

* [Bug middle-end/101955] (signed<<31)>>31 should become -(signed&1)
  2021-08-18  5:47 [Bug middle-end/101955] New: (signed<<31)>>31 should become -(signed&1) pinskia at gcc dot gnu.org
                   ` (4 preceding siblings ...)
  2021-08-18 19:22 ` jakub at gcc dot gnu.org
@ 2021-11-11  0:21 ` navidrahimi at microsoft dot com
  2023-08-04  7:10 ` cvs-commit at gcc dot gnu.org
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: navidrahimi at microsoft dot com @ 2021-11-11  0:21 UTC (permalink / raw)
  To: gcc-bugs

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

navidrahimi <navidrahimi at microsoft dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |navidrahimi at microsoft dot com

--- Comment #5 from navidrahimi <navidrahimi at microsoft dot com> ---
I think rather than just 

int f(int b)
{
    return (((b)<<31)>>31);
}

We should optimize long too:
int f(int b)
{
    return (((b)<<63)>>63);
}


1) https://compiler-explorer.com/z/dnrr54v4r

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

* [Bug middle-end/101955] (signed<<31)>>31 should become -(signed&1)
  2021-08-18  5:47 [Bug middle-end/101955] New: (signed<<31)>>31 should become -(signed&1) pinskia at gcc dot gnu.org
                   ` (5 preceding siblings ...)
  2021-11-11  0:21 ` navidrahimi at microsoft dot com
@ 2023-08-04  7:10 ` cvs-commit at gcc dot gnu.org
  2023-10-11  7:09 ` cvs-commit at gcc dot gnu.org
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-08-04  7:10 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #6 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:9020da78df2854f14f8b1d38b58a6d3b77a4b731

commit r14-2977-g9020da78df2854f14f8b1d38b58a6d3b77a4b731
Author: Drew Ross <drross@redhat.com>
Date:   Fri Aug 4 09:08:05 2023 +0200

    match.pd: Canonicalize (signed x << c) >> c [PR101955]

    Canonicalizes (signed x << c) >> c into the lowest
    precision(type) - c bits of x IF those bits have a mode precision or a
    precision of 1. Also combines this rule with (unsigned x << c) >> c -> x &
    ((unsigned)-1 >> c) to prevent duplicate pattern.

            PR middle-end/101955
            * match.pd ((signed x << c) >> c): New canonicalization.

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

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

* [Bug middle-end/101955] (signed<<31)>>31 should become -(signed&1)
  2021-08-18  5:47 [Bug middle-end/101955] New: (signed<<31)>>31 should become -(signed&1) pinskia at gcc dot gnu.org
                   ` (6 preceding siblings ...)
  2023-08-04  7:10 ` cvs-commit at gcc dot gnu.org
@ 2023-10-11  7:09 ` cvs-commit at gcc dot gnu.org
  2023-10-20 23:08 ` cvs-commit at gcc dot gnu.org
  2023-10-30 16:23 ` cvs-commit at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-10-11  7:09 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #7 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Roger Sayle <sayle@gcc.gnu.org>:

https://gcc.gnu.org/g:c41492423140e1573df68d1c98e825ae7593741f

commit r14-4551-gc41492423140e1573df68d1c98e825ae7593741f
Author: Roger Sayle <roger@nextmovesoftware.com>
Date:   Wed Oct 11 08:08:04 2023 +0100

    Optimize (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) as (and:SI x 1).

    This patch is the middle-end piece of an improvement to PRs 101955 and
    106245, that adds a missing simplification to the RTL optimizers.
    This transformation is to simplify (char)(x << 7) != 0 as x & 1.
    Technically, the cast can be any truncation, where shift is by one
    less than the narrower type's precision, setting the most significant
    (only) bit from the least significant bit.

    This transformation applies to any target, but it's easy to see
    (and add a new test case) on x86, where the following function:

    int f(int a) { return (a << 31) >> 31; }

    currently gets compiled with -O2 to:

    foo:    movl    %edi, %eax
            sall    $7, %eax
            sarb    $7, %al
            movsbl  %al, %eax
            ret

    but with this patch, we now generate the slightly simpler.

    foo:    movl    %edi, %eax
            sall    $31, %eax
            sarl    $31, %eax
            ret

    2023-10-11  Roger Sayle  <roger@nextmovesoftware.com>

    gcc/ChangeLog
            PR middle-end/101955
            PR tree-optimization/106245
            * simplify-rtx.cc (simplify_relational_operation_1): Simplify
            the RTL (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) to (and:SI x 1).

    gcc/testsuite/ChangeLog
            * gcc.target/i386/pr106245-1.c: New test case.

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

* [Bug middle-end/101955] (signed<<31)>>31 should become -(signed&1)
  2021-08-18  5:47 [Bug middle-end/101955] New: (signed<<31)>>31 should become -(signed&1) pinskia at gcc dot gnu.org
                   ` (7 preceding siblings ...)
  2023-10-11  7:09 ` cvs-commit at gcc dot gnu.org
@ 2023-10-20 23:08 ` cvs-commit at gcc dot gnu.org
  2023-10-30 16:23 ` cvs-commit at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-10-20 23:08 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #8 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Roger Sayle <sayle@gcc.gnu.org>:

https://gcc.gnu.org/g:e28869670c9879fe7c67caf6cc11af202509ef78

commit r14-4810-ge28869670c9879fe7c67caf6cc11af202509ef78
Author: Roger Sayle <roger@nextmovesoftware.com>
Date:   Sat Oct 21 00:06:02 2023 +0100

    PR 106245: Split (x<<31)>>31 as -(x&1) in i386.md

    This patch is the backend piece of a solution to PRs 101955 and 106245,
    that adds a define_insn_and_split to the i386 backend, to perform sign
    extension of a single (least significant) bit using and $1 then neg.

    Previously, (x<<31)>>31 would be generated as

            sall    $31, %eax       // 3 bytes
            sarl    $31, %eax       // 3 bytes

    with this patch the backend now generates:

            andl    $1, %eax        // 3 bytes
            negl    %eax            // 2 bytes

    Not only is this smaller in size, but microbenchmarking confirms
    that it's a performance win on both Intel and AMD; Intel sees only a
    2% improvement (perhaps just a size effect), but AMD sees a 7% win.

    2023-10-21  Roger Sayle  <roger@nextmovesoftware.com>
                Uros Bizjak  <ubizjak@gmail.com>

    gcc/ChangeLog
            PR middle-end/101955
            PR tree-optimization/106245
            * config/i386/i386.md (*extv<mode>_1_0): New define_insn_and_split.

    gcc/testsuite/ChangeLog
            PR middle-end/101955
            PR tree-optimization/106245
            * gcc.target/i386/pr106245-2.c: New test case.
            * gcc.target/i386/pr106245-3.c: New 32-bit test case.
            * gcc.target/i386/pr106245-4.c: New 64-bit test case.
            * gcc.target/i386/pr106245-5.c: Likewise.

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

* [Bug middle-end/101955] (signed<<31)>>31 should become -(signed&1)
  2021-08-18  5:47 [Bug middle-end/101955] New: (signed<<31)>>31 should become -(signed&1) pinskia at gcc dot gnu.org
                   ` (8 preceding siblings ...)
  2023-10-20 23:08 ` cvs-commit at gcc dot gnu.org
@ 2023-10-30 16:23 ` cvs-commit at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-10-30 16:23 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #9 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Roger Sayle <sayle@gcc.gnu.org>:

https://gcc.gnu.org/g:a3da9adeb457d4f01c4e695a9621f90c2e2a5e68

commit r14-5014-ga3da9adeb457d4f01c4e695a9621f90c2e2a5e68
Author: Roger Sayle <roger@nextmovesoftware.com>
Date:   Mon Oct 30 16:21:28 2023 +0000

    ARC: Convert (signed<<31)>>31 to -(signed&1) without barrel shifter.

    This patch optimizes PR middle-end/101955 for the ARC backend.  On ARC
    CPUs with a barrel shifter, using two shifts is optimal as:

            asl_s   r0,r0,31
            asr_s   r0,r0,31

    but without a barrel shifter, GCC -O2 -mcpu=em currently generates:

            and     r2,r0,1
            ror     r2,r2
            add.f   0,r2,r2
            sbc     r0,r0,r0

    with this patch, we now generate the smaller, faster and non-flags
    clobbering:

            bmsk_s  r0,r0,0
            neg_s   r0,r0

    2023-10-30  Roger Sayle  <roger@nextmovesoftware.com>

    gcc/ChangeLog
            PR middle-end/101955
            * config/arc/arc.md (*extvsi_1_0): New define_insn_and_split
            to convert sign extract of the least significant bit into an
            AND $1 then a NEG when !TARGET_BARREL_SHIFTER.

    gcc/testsuite/ChangeLog
            PR middle-end/101955
            * gcc.target/arc/pr101955.c: New test case.

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

end of thread, other threads:[~2023-10-30 16:23 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-18  5:47 [Bug middle-end/101955] New: (signed<<31)>>31 should become -(signed&1) pinskia at gcc dot gnu.org
2021-08-18  5:48 ` [Bug middle-end/101955] " pinskia at gcc dot gnu.org
2021-08-18  6:49 ` rguenth at gcc dot gnu.org
2021-08-18 15:51 ` schwab@linux-m68k.org
2021-08-18 17:51 ` pinskia at gcc dot gnu.org
2021-08-18 19:22 ` jakub at gcc dot gnu.org
2021-11-11  0:21 ` navidrahimi at microsoft dot com
2023-08-04  7:10 ` cvs-commit at gcc dot gnu.org
2023-10-11  7:09 ` cvs-commit at gcc dot gnu.org
2023-10-20 23:08 ` cvs-commit at gcc dot gnu.org
2023-10-30 16:23 ` cvs-commit 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).