https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128416
Bug ID: 128416
Summary: `std::bit_repeat(unsigned, C)` can be optimized better
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: enhancement
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: pinskia at gcc dot gnu.org
Target Milestone: ---
Target: aarch64
Take this code; I extracted bit_repeat from the headers so it can be used with
clang.
```
template <typename _Tp>
[[nodiscard]] constexpr _Tp bit_repeat(_Tp __x, int __l) {
constexpr auto _Nd = sizeof(_Tp)*8;
if (__l >= _Nd)
return __x;
__x &= ((_Tp)1 << __l) - 1;
do {
__x |= __x << __l;
__l <<= 1;
} while (__l < _Nd);
return __x;
}
unsigned f(unsigned x) { return bit_repeat(x, 31); }
```
Currently GCC produces:
```
and w1, w0, 2147483647
add w0, w1, w0, lsl 31
```
But this should just be:
```
bfi w0, w0, #31, #1
```
Which extracts bit 0 and inserts it as bit 31.
This is about optimizing the multiply really.
I noticed clang/LLVM optimizes even 15 to use bit extractions and inserts.