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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|GCC suboptimal loop         |Extra multiply with -Os due
                   |optimization: count-down to |to `(unsigned>>6) * -64`
                   |count-up conversion         |not being simplified to
                   |                            |`-(unsigned&0x3f)`
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1
           Severity|normal                      |enhancement
   Last reconfirmed|                            |2025-10-24
          Component|target                      |middle-end

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
  _31 = len_10(D) >> 6; // len_10(D)/64
  _32 = _31 * 18446744073709551552; // 31*-64

So this should be:
- (len_10 & 0x3f)


```
unsigned  long f(unsigned long a)
{
  a = a >> 6;
  return a * 64;
}

unsigned long f1(unsigned long a)
{
  a = a >> 6;
  return a * -64;
}
```

That is f is simplified to `a &-64` (though at the RTL level) while f1 is only
simplified for -O2 and NOT at -Os due to imul.

Reply via email to