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.

Reply via email to