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

            Bug ID: 92714
           Summary: [missed-optimization] aggregate initialization of an
                    array fills the whole array with zeros first,
                    including non-zero elements
           Product: gcc
           Version: 8.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: lassie.darkorbit at gmail dot com
  Target Milestone: ---

void *sink;
void bar() {
    int a[100]{1,2,3,4};
    sink = a;             // a escapes the function
    asm("":::"memory");   // and compiler memory barrier
    // forces the compiler to materialize a[] in memory instead of optimizing
away
}

gcc 8.1 and gcc 9.2 both make asm like this (even with -O3):

bar():
    push    edi                       # save call-preserved EDI which rep stos
uses
    xor     eax, eax                  # eax=0
    mov     ecx, 100                  # repeat-count = 100
    sub     esp, 400                  # reserve 400 bytes on the stack
    mov     edi, esp                  # dst for rep stos
        mov     DWORD PTR sink, esp       # sink = a
    rep stosd                         # memset(a, 0, 400) 

    mov     DWORD PTR [esp], 1        # then store the non-zero initializers
    mov     DWORD PTR [esp+4], 2      # over the zeroed part of the array
    mov     DWORD PTR [esp+8], 3
    mov     DWORD PTR [esp+12], 4

    add     esp, 400                  # cleanup the stack
    pop     edi                       # and restore caller's EDI
    ret

Reply via email to