Skip to content

[clang] memcmp-like function with pointer parameters and written as a for loop never transformed into memcmp #167397

@davidstone

Description

@davidstone

Given the following code

auto equal( int const * const lhs, int const * const rhs ) -> bool { for (int n = 0; n != 10; ++n) { if (lhs[n] != rhs[n]) { return false;	}	} return true; }

I would expect something like a call to memcmp for sufficiently large size. Instead, at -O3 it follows this pattern for 2 <= size <= 59:

equal(int const*, int const*):  mov eax, dword ptr [rdi]  cmp eax, dword ptr [rsi]  jne .LBB0_10  mov eax, dword ptr [rdi + 4]  cmp eax, dword ptr [rsi + 4]  jne .LBB0_10  mov eax, dword ptr [rdi + 8]  cmp eax, dword ptr [rsi + 8]  jne .LBB0_10  mov eax, dword ptr [rdi + 12]  cmp eax, dword ptr [rsi + 12]  jne .LBB0_10  mov eax, dword ptr [rdi + 16]  cmp eax, dword ptr [rsi + 16]  jne .LBB0_10  mov eax, dword ptr [rdi + 20]  cmp eax, dword ptr [rsi + 20]  jne .LBB0_10  mov eax, dword ptr [rdi + 24]  cmp eax, dword ptr [rsi + 24]  jne .LBB0_10  mov eax, dword ptr [rdi + 28]  cmp eax, dword ptr [rsi + 28]  jne .LBB0_10  mov eax, dword ptr [rdi + 32]  cmp eax, dword ptr [rsi + 32]  jne .LBB0_10  mov eax, dword ptr [rdi + 36]  cmp eax, dword ptr [rsi + 36]  sete al  ret .LBB0_10:  xor eax, eax  ret

And then for size >= 60 it does (with the constant adjusted appropriately)

equal(int const*, int const*):  xor eax, eax .LBB0_1:  mov ecx, dword ptr [rdi + 4*rax]  mov edx, dword ptr [rsi + 4*rax]  cmp ecx, edx  jne .LBB0_3  cmp rax, 59  lea rax, [rax + 1]  jne .LBB0_1 .LBB0_3:  cmp ecx, edx  sete al  ret

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