public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug rtl-optimization/109866] New: Sometimes using sub/test instead just test
@ 2023-05-15 18:44 pinskia at gcc dot gnu.org
2023-05-16 8:07 ` [Bug rtl-optimization/109866] " ubizjak at gmail dot com
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-05-15 18:44 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109866
Bug ID: 109866
Summary: Sometimes using sub/test instead just test
Product: gcc
Version: 14.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: enhancement
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: pinskia at gcc dot gnu.org
Target Milestone: ---
Take:
```
int g(void); int h(void); int t(void);
int f(int a, int b)
{
int c = a - b;
if(c == 0)
return g();
if (c > 0)
return h();
return t();
}
```
This is reduced from bzip2 in spec 2006, though I am not so sure any more.
On x86_64 GCC produces:
```
subl %esi, %edi
testl %edi, %edi
je .L5
jle .L3
jmp h()
.L3:
jmp t()
.L5:
jmp g()
```
But GCC should produce (likes clang/LLVM does):
```
cmpl %esi, %edi
je .L5
jle .L3
jmp h()
.L3:
jmp t()
.L5:
jmp g()
```
Note a similar thing happens with aarch64 target too.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug rtl-optimization/109866] Sometimes using sub/test instead just test
2023-05-15 18:44 [Bug rtl-optimization/109866] New: Sometimes using sub/test instead just test pinskia at gcc dot gnu.org
@ 2023-05-16 8:07 ` ubizjak at gmail dot com
2023-05-16 8:19 ` ubizjak at gmail dot com
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: ubizjak at gmail dot com @ 2023-05-16 8:07 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109866
--- Comment #1 from Uroš Bizjak <ubizjak at gmail dot com> ---
(In reply to Andrew Pinski from comment #0)
> Take:
> ```
> int g(void); int h(void); int t(void);
> int f(int a, int b)
> {
> int c = a - b;
> if(c == 0)
> return g();
> if (c > 0)
> return h();
> return t();
> }
> ```
> This is reduced from bzip2 in spec 2006, though I am not so sure any more.
> On x86_64 GCC produces:
> ```
> subl %esi, %edi
> testl %edi, %edi
> je .L5
> jle .L3
> jmp h()
> .L3:
> jmp t()
> .L5:
> jmp g()
> ```
> But GCC should produce (likes clang/LLVM does):
> ```
> cmpl %esi, %edi
> je .L5
> jle .L3
> jmp h()
> .L3:
> jmp t()
> .L5:
> jmp g()
> ```
>
> Note a similar thing happens with aarch64 target too.
These two assemblies are not equal as demonstrated by the following test:
--cut here--
#include <stdio.h>
_Bool
__attribute__((noinline))
foo (int a, int b)
{
_Bool r;
int tmp;
asm ("subl %3, %0; testl %0, %0"
: "=r"(tmp), "=@cc" "le"(r)
: "0"(a), "r"(b));
return r;
}
_Bool
__attribute__((noinline))
bar (int a, int b)
{
_Bool r;
asm ("cmpl %2, %1"
: "=@cc" "le"(r)
: "r"(a), "r"(b));
return r;
}
int
main ()
{
int a, b;
_Bool ra, rb;
a = 0x80000000, b = 0x40000000;
ra = foo (a, b);
rb = bar (a, b);
printf ("%i %i\n", ra, rb);
return 0;
}
--cut here--
$ ./a.out
0 1
The difference is in handling of overflow flag.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug rtl-optimization/109866] Sometimes using sub/test instead just test
2023-05-15 18:44 [Bug rtl-optimization/109866] New: Sometimes using sub/test instead just test pinskia at gcc dot gnu.org
2023-05-16 8:07 ` [Bug rtl-optimization/109866] " ubizjak at gmail dot com
@ 2023-05-16 8:19 ` ubizjak at gmail dot com
2023-05-16 10:24 ` pinskia at gcc dot gnu.org
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: ubizjak at gmail dot com @ 2023-05-16 8:19 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109866
--- Comment #2 from Uroš Bizjak <ubizjak at gmail dot com> ---
A small improvement would be:
subl %esi, %edi
je .L5
testl %edi, %edi
jle .L3
jmp h()
.L3:
jmp t()
.L5:
jmp g()
Not to mention the unoptimal handling of tail calls...
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug rtl-optimization/109866] Sometimes using sub/test instead just test
2023-05-15 18:44 [Bug rtl-optimization/109866] New: Sometimes using sub/test instead just test pinskia at gcc dot gnu.org
2023-05-16 8:07 ` [Bug rtl-optimization/109866] " ubizjak at gmail dot com
2023-05-16 8:19 ` ubizjak at gmail dot com
@ 2023-05-16 10:24 ` pinskia at gcc dot gnu.org
2023-05-16 15:50 ` [Bug tree-optimization/109866] " pinskia at gcc dot gnu.org
2023-05-17 6:56 ` rguenth at gcc dot gnu.org
4 siblings, 0 replies; 6+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-05-16 10:24 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109866
--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Uroš Bizjak from comment #1)
> (In reply to Andrew Pinski from comment #0)
> > Take:
> > ```
> > int g(void); int h(void); int t(void);
> > int f(int a, int b)
> > {
> > int c = a - b;
> > if(c == 0)
> > return g();
> > if (c > 0)
> > return h();
> > return t();
> > }
> > ```
> > This is reduced from bzip2 in spec 2006, though I am not so sure any more.
> > On x86_64 GCC produces:
> > ```
> > subl %esi, %edi
> > testl %edi, %edi
> > je .L5
> > jle .L3
> > jmp h()
> > .L3:
> > jmp t()
> > .L5:
> > jmp g()
> > ```
> > But GCC should produce (likes clang/LLVM does):
> > ```
> > cmpl %esi, %edi
> > je .L5
> > jle .L3
> > jmp h()
> > .L3:
> > jmp t()
> > .L5:
> > jmp g()
> > ```
> >
> > Note a similar thing happens with aarch64 target too.
>
> These two assemblies are not equal as demonstrated by the following test:
>
> --cut here--
> #include <stdio.h>
>
> _Bool
> __attribute__((noinline))
> foo (int a, int b)
> {
> _Bool r;
> int tmp;
>
> asm ("subl %3, %0; testl %0, %0"
> : "=r"(tmp), "=@cc" "le"(r)
> : "0"(a), "r"(b));
> return r;
> }
>
> _Bool
> __attribute__((noinline))
> bar (int a, int b)
> {
> _Bool r;
>
> asm ("cmpl %2, %1"
> : "=@cc" "le"(r)
> : "r"(a), "r"(b));
> return r;
> }
>
> int
> main ()
> {
> int a, b;
> _Bool ra, rb;
>
> a = 0x80000000, b = 0x40000000;
> ra = foo (a, b);
> rb = bar (a, b);
>
> printf ("%i %i\n", ra, rb);
> return 0;
> }
> --cut here--
>
> $ ./a.out
> 0 1
>
> The difference is in handling of overflow flag.
Right but 0x80000000 - 0x40000000 is undefined for signed integers ...
If this was unsigned subtraction then I would say it is they are different.
Note maybe RTL level is not the best place for this optimization as subtraction
already lost if it is undefined on overflow or not ...
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug tree-optimization/109866] Sometimes using sub/test instead just test
2023-05-15 18:44 [Bug rtl-optimization/109866] New: Sometimes using sub/test instead just test pinskia at gcc dot gnu.org
` (2 preceding siblings ...)
2023-05-16 10:24 ` pinskia at gcc dot gnu.org
@ 2023-05-16 15:50 ` pinskia at gcc dot gnu.org
2023-05-17 6:56 ` rguenth at gcc dot gnu.org
4 siblings, 0 replies; 6+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-05-16 15:50 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109866
Andrew Pinski <pinskia at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Component|rtl-optimization |tree-optimization
--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
So I think forwprop could/should do this.
Right now it requires c to be single use but we should detect that somehow a-b
use is reverse dominated by the first use of c. Anyways this might require a
rewrite of parts of forwprop ...
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug tree-optimization/109866] Sometimes using sub/test instead just test
2023-05-15 18:44 [Bug rtl-optimization/109866] New: Sometimes using sub/test instead just test pinskia at gcc dot gnu.org
` (3 preceding siblings ...)
2023-05-16 15:50 ` [Bug tree-optimization/109866] " pinskia at gcc dot gnu.org
@ 2023-05-17 6:56 ` rguenth at gcc dot gnu.org
4 siblings, 0 replies; 6+ messages in thread
From: rguenth at gcc dot gnu.org @ 2023-05-17 6:56 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109866
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Ever confirmed|0 |1
Last reconfirmed| |2023-05-17
--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #4)
> So I think forwprop could/should do this.
> Right now it requires c to be single use but we should detect that somehow
> a-b use is reverse dominated by the first use of c. Anyways this might
> require a rewrite of parts of forwprop ...
I think we could relax the single-use restriction to allow multiple uses
in comparisons. Though I hoped to eventually get rid of the non-match.pd
comparison forwarding in the pass ...
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2023-05-17 6:56 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-15 18:44 [Bug rtl-optimization/109866] New: Sometimes using sub/test instead just test pinskia at gcc dot gnu.org
2023-05-16 8:07 ` [Bug rtl-optimization/109866] " ubizjak at gmail dot com
2023-05-16 8:19 ` ubizjak at gmail dot com
2023-05-16 10:24 ` pinskia at gcc dot gnu.org
2023-05-16 15:50 ` [Bug tree-optimization/109866] " pinskia at gcc dot gnu.org
2023-05-17 6:56 ` rguenth 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).