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

            Bug ID: 87223
           Summary: -Os produces sub-optimal x86 machine code for
                    initialization with zero
           Product: gcc
           Version: 8.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jens.maurer at gmx dot net
  Target Milestone: ---

My understanding of -Os is that it is aimed at reducing code size. It produces
code with suboptimal size for the constructor below (and similar cases where a
constructor needs to initialize lots of members to zero):

struct S {
  char a = 0;
  void * b = 0;
  short c = 0;
  long d = 0;

  S();
};

S::S() = default;

Generated code on x86-64 using "g++ -Os -S x.cc":

        movb    $0, (%rdi)
        movq    $0, 8(%rdi)
        movw    $0, 16(%rdi)
        movq    $0, 24(%rdi)
        ret

It would be more efficient space-wise to first zero a register with "xor %eax,
%eax" (should implicitly zero all of %rax) and then use %rax or a sub-register
thereof as the source for the moves. This avoids putting 0 as constants into
the machine instructions over and over again, enlarging their size (and, due to
their size, possibly clogging the CPU's instruction decoder).

Reply via email to