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

Reply via email to