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.

Reply via email to