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).