https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70782
Bug ID: 70782 Summary: zero-initialized union returned by value generates useless stores/loads to the stack Product: gcc Version: 5.2.1 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: jhaberman at gmail dot com Target Milestone: --- Test case: -- #include <string.h> typedef union { char ch; float fl; double dbl; } u; u f(const void *p, int type) { u v; memset(&v, 0, 8); if (type == 1) { memcpy(&v, p, 1); } else if (type <= 5) { memcpy(&v, p, 4); } else if (type <= 8) { memcpy(&v, p, 8); } return v; } -- With gcc 5.2.1 on Ubuntu, compiled with -O3 -fno-stack-protect I get: -- 0000000000000000 <f>: 0: 83 fe 01 cmp esi,0x1 3: 48 c7 44 24 e8 00 00 mov QWORD PTR [rsp-0x18],0x0 a: 00 00 c: 74 32 je 40 <f+0x40> e: 83 fe 05 cmp esi,0x5 11: 7e 1d jle 30 <f+0x30> 13: 83 fe 08 cmp esi,0x8 16: 7f 08 jg 20 <f+0x20> 18: 48 8b 07 mov rax,QWORD PTR [rdi] 1b: 48 89 44 24 e8 mov QWORD PTR [rsp-0x18],rax 20: 48 8b 44 24 e8 mov rax,QWORD PTR [rsp-0x18] 25: c3 ret 26: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0] 2d: 00 00 00 30: 8b 07 mov eax,DWORD PTR [rdi] 32: 89 44 24 e8 mov DWORD PTR [rsp-0x18],eax 36: 48 8b 44 24 e8 mov rax,QWORD PTR [rsp-0x18] 3b: c3 ret 3c: 0f 1f 40 00 nop DWORD PTR [rax+0x0] 40: 0f b6 07 movzx eax,BYTE PTR [rdi] 43: 88 44 24 e8 mov BYTE PTR [rsp-0x18],al 47: 48 8b 44 24 e8 mov rax,QWORD PTR [rsp-0x18] 4c: c3 ret -- In every code path it saves the read value to the stack, only to read it back. None of these operations are actually necessary, since the code is already zeroing the other parts of rax. This function shouldn't need to use any stack space at all.