public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug tree-optimization/114341] New: Optimization opportunity with {mul,div} "(x & -x)" and {<<,>>} "ctz(x)"
@ 2024-03-14 23:06 Explorer09 at gmail dot com
  2024-03-14 23:08 ` [Bug tree-optimization/114341] " pinskia at gcc dot gnu.org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Explorer09 at gmail dot com @ 2024-03-14 23:06 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 114341
           Summary: Optimization opportunity with {mul,div} "(x & -x)" and
                    {<<,>>} "ctz(x)"
           Product: gcc
           Version: 13.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: Explorer09 at gmail dot com
  Target Milestone: ---

This is an optimization opportunity that I'm not sure it's worth
implementing in gcc, since I only used the (x / (x & -x)) pattern on
compile time constants only.

When x and y are unsigned integers and the value of y is non-zero,
then (x / (y & -y)) and (x >> __builtin_ctz(y)) are equivalent.

Similarly, (x * (y & -y)) and (x << __builtin_ctz(y)) are equivalent.

One reason for using the (x / (y & -y)) pattern is that it's more
portable among C compilers before C23 made a standard "CTZ" API
(stdc_trailing_zeros) for everyone. Even though we have
stdc_trailing_zeros() now, the (x / (y & -y)) pattern is still useful
for constant expressions when stdc_trailing_zeros() might not be a
compiler built in.

Processors that support CTZ instructions would optimize (x / (y & -y))
to (x >> __builtin_ctz(y)); processors that do not support CTZ would
optimize the other way around. (I know RISC-V might need the latter
way of optimization.)

```c
unsigned int func1a(unsigned int x, unsigned int y) {
  if (y == 0)
    return -1; /* placeholder value to indicate error */

  return x / (y & -y);
}

unsigned int func1b(unsigned int x, unsigned int y) {
  if (y == 0)
    return -1; /* placeholder value to indicate error */

  return x >> __builtin_ctz(y);
}

unsigned int func2a(unsigned int x, unsigned int y) {
  if (y == 0)
    return -1; /* placeholder value to indicate error */

  return x * (y & -y);
}

unsigned int func2b(unsigned int x, unsigned int y) {
  if (y == 0)
    return -1; /* placeholder value to indicate error */

  return x << __builtin_ctz(y);
}
```

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

* [Bug tree-optimization/114341] Optimization opportunity with {mul,div} "(x & -x)" and {<<,>>} "ctz(x)"
  2024-03-14 23:06 [Bug tree-optimization/114341] New: Optimization opportunity with {mul,div} "(x & -x)" and {<<,>>} "ctz(x)" Explorer09 at gmail dot com
@ 2024-03-14 23:08 ` pinskia at gcc dot gnu.org
  2024-03-14 23:12 ` pinskia at gcc dot gnu.org
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-03-14 23:08 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
x/(y&-y) is already recorded as PR 97738 .

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

* [Bug tree-optimization/114341] Optimization opportunity with {mul,div} "(x & -x)" and {<<,>>} "ctz(x)"
  2024-03-14 23:06 [Bug tree-optimization/114341] New: Optimization opportunity with {mul,div} "(x & -x)" and {<<,>>} "ctz(x)" Explorer09 at gmail dot com
  2024-03-14 23:08 ` [Bug tree-optimization/114341] " pinskia at gcc dot gnu.org
@ 2024-03-14 23:12 ` pinskia at gcc dot gnu.org
  2024-03-15  8:47 ` Explorer09 at gmail dot com
  2024-03-15  9:01 ` pinskia at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-03-14 23:12 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2024-03-14
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1
           Keywords|                            |missed-optimization
                 CC|                            |pinskia at gcc dot gnu.org
           Severity|normal                      |enhancement

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Confirmed for the multiply as I mentioned the divide is already recorded.

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

* [Bug tree-optimization/114341] Optimization opportunity with {mul,div} "(x & -x)" and {<<,>>} "ctz(x)"
  2024-03-14 23:06 [Bug tree-optimization/114341] New: Optimization opportunity with {mul,div} "(x & -x)" and {<<,>>} "ctz(x)" Explorer09 at gmail dot com
  2024-03-14 23:08 ` [Bug tree-optimization/114341] " pinskia at gcc dot gnu.org
  2024-03-14 23:12 ` pinskia at gcc dot gnu.org
@ 2024-03-15  8:47 ` Explorer09 at gmail dot com
  2024-03-15  9:01 ` pinskia at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: Explorer09 at gmail dot com @ 2024-03-15  8:47 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Kang-Che Sung <Explorer09 at gmail dot com> ---
I missed one case that is more obvious:
(1 << __builtin_ctz(y)) == (y & -y)

Multiplication is not needed in this case, and thus (1 << __builtin_ctz(y)) can
simplify to (y & -y). (I didn't think of a reason we need to optimize the other
way around for this special case.)

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

* [Bug tree-optimization/114341] Optimization opportunity with {mul,div} "(x & -x)" and {<<,>>} "ctz(x)"
  2024-03-14 23:06 [Bug tree-optimization/114341] New: Optimization opportunity with {mul,div} "(x & -x)" and {<<,>>} "ctz(x)" Explorer09 at gmail dot com
                   ` (2 preceding siblings ...)
  2024-03-15  8:47 ` Explorer09 at gmail dot com
@ 2024-03-15  9:01 ` pinskia at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-03-15  9:01 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Kang-Che Sung from comment #3)
> I missed one case that is more obvious:
> (1 << __builtin_ctz(y)) == (y & -y)
> 
> Multiplication is not needed in this case, and thus (1 << __builtin_ctz(y))
> can simplify to (y & -y). (I didn't think of a reason we need to optimize
> the other way around for this special case.)

Well __builtin_ctz(y) is not well defined for y==0. But maybe that is ok here.

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

end of thread, other threads:[~2024-03-15  9:01 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-14 23:06 [Bug tree-optimization/114341] New: Optimization opportunity with {mul,div} "(x & -x)" and {<<,>>} "ctz(x)" Explorer09 at gmail dot com
2024-03-14 23:08 ` [Bug tree-optimization/114341] " pinskia at gcc dot gnu.org
2024-03-14 23:12 ` pinskia at gcc dot gnu.org
2024-03-15  8:47 ` Explorer09 at gmail dot com
2024-03-15  9:01 ` 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).