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