public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug tree-optimization/94893] New: Sign function not getting optimized to simple compare
@ 2020-04-30 17:31 gabravier at gmail dot com
2020-09-04 8:55 ` [Bug tree-optimization/94893] " gabravier at gmail dot com
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: gabravier at gmail dot com @ 2020-04-30 17:31 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94893
Bug ID: 94893
Summary: Sign function not getting optimized to simple compare
Product: gcc
Version: 10.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: gabravier at gmail dot com
Target Milestone: ---
inline int sign(int x)
{
return (x >> 31) | ((unsigned)-x >> 31);
}
bool f(int x)
{
return sign(x) < 1;
}
With -O3, LLVM outputs :
f(int):
test edi, edi
setle al
ret
GCC outputs :
f(int):
mov eax, edi
sar edi, 31
neg eax
shr eax, 31
or eax, edi
setle al
ret
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Bug tree-optimization/94893] Sign function not getting optimized to simple compare
2020-04-30 17:31 [Bug tree-optimization/94893] New: Sign function not getting optimized to simple compare gabravier at gmail dot com
@ 2020-09-04 8:55 ` gabravier at gmail dot com
2021-04-26 0:52 ` pinskia at gcc dot gnu.org
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: gabravier at gmail dot com @ 2020-09-04 8:55 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94893
Gabriel Ravier <gabravier at gmail dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
Target|x86_64-*-* |
Blocks| |19987
--- Comment #1 from Gabriel Ravier <gabravier at gmail dot com> ---
No idea why it was marked as x86-specific, it isn't as far as I can see, so I
removed the target here. Do tell me if this is wrong.
Referenced Bugs:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19987
[Bug 19987] [meta-bug] fold missing optimizations in general
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Bug tree-optimization/94893] Sign function not getting optimized to simple compare
2020-04-30 17:31 [Bug tree-optimization/94893] New: Sign function not getting optimized to simple compare gabravier at gmail dot com
2020-09-04 8:55 ` [Bug tree-optimization/94893] " gabravier at gmail dot com
@ 2021-04-26 0:52 ` pinskia at gcc dot gnu.org
2021-04-26 1:01 ` pinskia at gcc dot gnu.org
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-04-26 0:52 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94893
Andrew Pinski <pinskia at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Severity|normal |enhancement
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Bug tree-optimization/94893] Sign function not getting optimized to simple compare
2020-04-30 17:31 [Bug tree-optimization/94893] New: Sign function not getting optimized to simple compare gabravier at gmail dot com
2020-09-04 8:55 ` [Bug tree-optimization/94893] " gabravier at gmail dot com
2021-04-26 0:52 ` pinskia at gcc dot gnu.org
@ 2021-04-26 1:01 ` pinskia at gcc dot gnu.org
2023-05-13 5:17 ` pinskia at gcc dot gnu.org
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-04-26 1:01 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94893
Andrew Pinski <pinskia at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Ever confirmed|0 |1
Last reconfirmed| |2021-04-26
Status|UNCONFIRMED |NEW
--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Confirmed.
Note the original code does have one slight undefined case, when x is INT_MIN
but that can be fixed by casting to unsigned before doing the negate of x.
That is:
inline int sign(int x)
{
return (x >> 31) | (-(unsigned)x >> 31);
}
---- CUT ----
Matching this:
_1 = x_5(D) >> 31;
x.0_2 = (unsigned int) x_5(D);
_3 = -x.0_2;
_4 = _3 >> 31;
_8 = (int) _4;
_6 = _1 | _8;
Into:
t = (int)(x > 0);
result = x < 0 ? - 1 : t;
Might not be the best thing.
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Bug tree-optimization/94893] Sign function not getting optimized to simple compare
2020-04-30 17:31 [Bug tree-optimization/94893] New: Sign function not getting optimized to simple compare gabravier at gmail dot com
` (2 preceding siblings ...)
2021-04-26 1:01 ` pinskia at gcc dot gnu.org
@ 2023-05-13 5:17 ` pinskia at gcc dot gnu.org
2023-08-24 4:05 ` pinskia at gcc dot gnu.org
2023-08-24 4:37 ` pinskia at gcc dot gnu.org
5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-05-13 5:17 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94893
--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Note we also don't optimize:
inline int sign1(int x)
{
return (x < 0 ? -1 : 0) | (x > 0 ? 1 : 0);
}
bool f1(int x)
{
return sign1(x) < 1;
}
To be just `x <= 0`
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Bug tree-optimization/94893] Sign function not getting optimized to simple compare
2020-04-30 17:31 [Bug tree-optimization/94893] New: Sign function not getting optimized to simple compare gabravier at gmail dot com
` (3 preceding siblings ...)
2023-05-13 5:17 ` pinskia at gcc dot gnu.org
@ 2023-08-24 4:05 ` pinskia at gcc dot gnu.org
2023-08-24 4:37 ` pinskia at gcc dot gnu.org
5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-08-24 4:05 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94893
Andrew Pinski <pinskia at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Assignee|unassigned at gcc dot gnu.org |pinskia at gcc dot gnu.org
Status|NEW |ASSIGNED
--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #3)
> Note we also don't optimize:
>
> inline int sign1(int x)
> {
> return (x < 0 ? -1 : 0) | (x > 0 ? 1 : 0);
> }
> bool f1(int x)
> {
> return sign1(x) < 1;
> }
>
> To be just `x <= 0`
That is because forwprop leaves assignments that are not used anywhere still.
after dce7:
```
if (x_2(D) < 0)
goto <bb 4>; [41.00%]
else
goto <bb 3>; [59.00%]
<bb 3> [local count: 633507680]:
_7 = x_2(D) != 0;
_8 = (int) _7;
_5 = _8 ^ 1;
_10 = (bool) _5;
<bb 4> [local count: 1073741824]:
# prephitmp_11 = PHI <1(2), _10(3)>
```
After frowprop4:
```
if (x_2(D) < 0)
goto <bb 4>; [41.00%]
else
goto <bb 3>; [59.00%]
<bb 3> [local count: 633507680]:
_7 = x_2(D) != 0;
_8 = (int) _7;
_3 = x_2(D) == 0;
_5 = (int) _3;
<bb 4> [local count: 1073741824]:
# prephitmp_11 = PHI <1(2), _3(3)>
```
If those statements were removed then phiopt4 would be able to optimize
prephitmp_11 to: `(x_2(D) < 0) | (x_2(D) == 0)` which simplifies to `x_2(D) <=
0` .
Let me look into the forwprop issue here.
As for the original issue:
x.0_5 = (unsigned int) x_2(D);
_6 = -x.0_5;
_7 = _6 >> 31;
_8 = (int) _7;
We have a pattern for basically this:
/* Fold (-x >> C) into -(x > 0) where C = precision(type) - 1. */
But only for !TYPE_UNSIGNED here. we can do it for unsigned where we just get x
> 0 instead.
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Bug tree-optimization/94893] Sign function not getting optimized to simple compare
2020-04-30 17:31 [Bug tree-optimization/94893] New: Sign function not getting optimized to simple compare gabravier at gmail dot com
` (4 preceding siblings ...)
2023-08-24 4:05 ` pinskia at gcc dot gnu.org
@ 2023-08-24 4:37 ` pinskia at gcc dot gnu.org
5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-08-24 4:37 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94893
--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #4)
> As for the original issue:
> x.0_5 = (unsigned int) x_2(D);
> _6 = -x.0_5;
> _7 = _6 >> 31;
> _8 = (int) _7;
>
> We have a pattern for basically this:
> /* Fold (-x >> C) into -(x > 0) where C = precision(type) - 1. */
>
> But only for !TYPE_UNSIGNED here. we can do it for unsigned where we just
> get x > 0 instead.
I have a patch which gets us to:
# RANGE [irange] int [-1, 0]
_3 = x_2(D) >> 31;
_5 = x_2(D) > 0;
# RANGE [irange] int [0, 1] MASK 0x1 VALUE 0x0
_6 = (intD.9) _5;
# RANGE [irange] int [-1, 1]
_7 = _3 | _6;
_4 = _7 != 1;
(_3 | _6) != 1 means !((_3 == 0) && (_6 == 1)) since _3 can't be 1 at all.
(_3 == 0) is x >= 0 and _6 == 1 is `x > 0` and that combines to be just `x >=
0` .
I think the above only works if the two ranges in the _3|_6 is [-1,0] and [1,0]
.
(_3 | _6) == -1 just means _3 == -1 even which we don't handle either (and
would be simplier to handle than other cases).
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2023-08-24 4:37 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-30 17:31 [Bug tree-optimization/94893] New: Sign function not getting optimized to simple compare gabravier at gmail dot com
2020-09-04 8:55 ` [Bug tree-optimization/94893] " gabravier at gmail dot com
2021-04-26 0:52 ` pinskia at gcc dot gnu.org
2021-04-26 1:01 ` pinskia at gcc dot gnu.org
2023-05-13 5:17 ` pinskia at gcc dot gnu.org
2023-08-24 4:05 ` pinskia at gcc dot gnu.org
2023-08-24 4:37 ` 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).