https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105051

            Bug ID: 105051
           Summary: consider not combining malloc + memset to calloc when
                    inside calloc itself
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: godmar at gmail dot com
  Target Milestone: ---

gcc 8.5.0 (and later) just broke our 18-year-old calloc implementation, which
goes like this:

void *
calloc (size_t a, size_t b)
{
  /* Calculate block size and make sure it fits in size_t. */
  size_t size = a * b;

  /* Allocate and zero memory. */
  void *p = malloc (size);
  if (p != NULL)
    memset (p, 0, size);

  return p;
}

by producing this ingenuous code sequence:

calloc:
    imulq   %rsi, %rdi
    movl    $1, %esi
    jmp calloc


I believe that this is due to an optimization whereby a sequence of malloc
followed by memset is transformed into a call to calloc.

My suggestion would be to suppress this optimization inside a function that is
itself called calloc as it leads to an infinite loop.

I'm also curious what the proper work-around is.  Is it `-fno-builtin-memset`?

I discovered this in 8.5.0 but Godbolt says it's present in the trunk as of
now:
https://godbolt.org/z/MKMT98qnr

This may be related to Bug #83022

Reply via email to