https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82845
Bug ID: 82845
Summary: -ftree-loop-distribute-patterns creates recursive
loops on function called "memset"
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: david at westcontrol dot com
Target Milestone: ---
(I have tested this using several gcc versions, including x86_64 and arm ports,
up to an 8.0.0 trunk test version.)
The -ftree-loop-distribute-patterns optimisation spots constructs that look
like memset, memcpy, etc., calls - and generates library calls to these
functions to give fast code using the library routines rather than generating
large amounts of inline code (so that the set or copy operations can be done in
lumps larger than one byte at a time).
But if you have have your own implementation of one of these functions (as may
be done for tracing calls, or in some embedded systems - or simply because you
are writing a C library), the call does not go to the library version - it will
go to the new local definition of the function. For example, given this simple
memset implementation:
void *memset(void *s, int c, size_t n)
{
char *p = s;
while (n--) *p++ = c;
return s;
}
gcc on x86_64 with -O2 gives simple, solid code:
memset:
testq %rdx, %rdx
movq %rdi, %rax
je .L6
addq %rdi, %rdx
movq %rdi, %rcx
.L3:
addq $1, %rcx
movb %sil, -1(%rcx)
cmpq %rdx, %rcx
jne .L3
.L6:
rep ret
With -O3, which enables -ftree-loop-distribute-patterns, it gives:
memset:
testq %rdx, %rdx
je .L6
subq $8, %rsp
movsbl %sil, %esi
call memset
addq $8, %rsp
ret
.L6:
movq %rdi, %rax
ret
gcc spots that the loop is like an memset, and replaces it with a call to
memset. But now that leads to infinite recursion.