Skip to content

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

@davidstone

Description

@davidstone

Given the following code:

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)

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

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions