llvm / llvm/llvm-project

[clang] `memcmp`-like function written as a for loop not transformed to `memcmp` for large arrays

Open
#167,389 4 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

Given the following code:

```c++
constexpr auto size = SIZE;

struct array {
int m[size];
};

auto equal(
array const lhs,
array const rhs
) -> bool {
for (int n = 0; n != size; ++n) {
if (lhs.m[n] != rhs.m[n]) {
return false;
}
}
return true;
}
```

With `-O3` and `SIZE` defined as any number between 9 and 59 inclusive, clang generates (with different constants)

```asm
equal(array, array):
push rax
lea rdi, [rsp + 16]
lea rsi, [rsp + 256]
mov edx, 236
call memcmp@PLT
test eax, eax
sete al
pop rcx
ret
```

but when `SIZE` is defined to be 60 or larger, clang generates

```asm
equal(array, array):
lea rax, [rsp + 248]
lea rcx, [rsp + 8]
xor edx, edx
.LBB0_1:
mov esi, dword ptr [rcx + 4*rdx]
mov edi, dword ptr [rax + 4*rdx]
cmp esi, edi
jne .LBB0_3
cmp rdx, 59
lea rdx, [rdx + 1]
jne .LBB0_1
.LBB0_3:
cmp esi, edi
sete al
ret
```

See it live: https://godbolt.org/z/xfsdd7Ks8

I would expect that if it ever makes sense to generate a call to `memcmp`, it would continue to make sense for larger sizes.

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the SIZE 59-versus-60 behavior from the issue using the linked Compiler Explorer example and the shown -O3 assembly. Trace the optimization responsible for recognizing the loop as memcmp-like and determine whether the threshold is intentional. Done means the behavior is explained or corrected, with a regression test covering larger arrays.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.