* [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