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.

Reply via email to