| Issue |
71316
|
| Summary |
Missed optimization: unnecessary register move
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
dvyukov
|
The code is:
```
struct SlabList {
bool Free(void* ptr) __restrict;
void* head_ = nullptr;
void* batch_ = nullptr;
void* tail_ = nullptr;
uint32_t size_ = 0;
const uint32_t capacity_;
};
bool SlabList::Free(void* __restrict ptr) __restrict {
constexpr uint32_t batch_size = 64;
if (__builtin_expect((size_ & (batch_size - 1)) != 0, true)) {
((void**)ptr)[0] = head_;
((void**)ptr)[1] = batch_;
head_ = ptr;
size_ += 1;
return true;
}
if (__builtin_expect(size_ == capacity_, false)) {
return false;
}
tail_ = ptr;
head_ = ptr;
batch_ = ptr;
size_ += 1;
return true;
}
```
The fast path code that clang generates is:
``
SlabList::Free(void*):
mov 0x18(%rdi),%eax
test $0x3f,%al
je 114b <SlabList::Free(void*)+0x1b>
movups (%rdi),%xmm0
movups %xmm0,(%rsi)
mov %rdi,%rcx
mov %rsi,(%rcx)
inc %eax
mov %eax,0x18(%rdi)
mov $0x1,%al
ret
```
The `mov %rdi,%rcx` instruction is unnecessary.
https://godbolt.org/z/zah88ecYf
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs