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