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.