llvm / llvm/llvm-project

Doesn't recognise open-coded memchr() (like in std::count(char *, char *, char)), so produces code 40% slower than if it used memchr()

Open
#173,497 0 comments 0 reactions 0 assignees View on GitHub
llvm:optimizations missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

With a
```cpp
char buf[64 * 1024];
ssize_t rd = read(fd, buf, sizeof(buf));
```
preamble
```cpp
acc += std::count(buf, buf + rd, '\n');
```
is 40-50% slower than
```cpp
auto newitr = buf;
auto len = rd;
char * itr;
// This is still suboptimal: a while(itr != end && *itr == '\n') ++acc; will be better if the data has consecutive needles but this is covered by std::count
while(len && (newitr = static_cast(std::memchr(itr = newitr, '\n', len)))) {
++acc.newlines;
++newitr;
len -= newitr - itr;
}
```
on clang trunk 1:21.0-61~exp1+0~20250421201207.11~1.gbp5a3b95.

Full program and dataset at , where I observe, for a 184M file with 290957 lines of line-delimited JSON, std::count takes ~140ms and memchr takes ~67ms on E5645.

The same happens on libc++.

`perf record` shows 62% in the lambda for std::count and 25% in __memchr_sse2 for memchr.

LLVM should understand that for a `Byte * beg, end`, `while(beg != end && *beg == needle) ++beg;` is an open-coding of memchr() and reify that to memchr.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.