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

            Bug ID: 92486
           Summary: Wrong optimization: padding in structs is not copied
                    even with memcpy
           Product: gcc
           Version: 9.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ch3root at openwall dot com
  Target Milestone: ---

Sometimes padding in structs is not copied even with memcpy. AIUI this is
considered a bug in gcc (similar to pr71452 and pr71522). The code:

----------------------------------------------------------------------

#include <string.h>
#include <stdio.h>

struct s {
    char c;
    int i;
};

__attribute__((noinline,noclone))
void f(struct s *p, struct s *q)
{
    struct s w = *q;
    memcpy(&w, q, sizeof(struct s));

    *p = w;
    memcpy(p, &w, sizeof(struct s));
}

int main()
{
    struct s x;
    memset(&x, 1, sizeof(struct s));

    struct s y;
    memset(&y, 2, sizeof(struct s));

    f(&y, &x);

    for (unsigned char *p = (unsigned char *)&y; p < (unsigned char *)&y +
sizeof(struct s); p++)
        printf("%d", *p);
    printf("\n");
}

----------------------------------------------------------------------

According to https://godbolt.org/z/fSEGka, x86-64 gcc, versions from 6.3 to 9.2
(but not trunk), with options `-std=c11 -Wall -Wextra -pedantic -O3` miscompile
the function `f` and the program outputs `12221111` instead of `11111111`. I
guess that `memcpy`s are optimized away as they fully duplicate assignments,
then assignments are scalarized and the padding is lost.

Reply via email to