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).