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

            Bug ID: 121653
           Summary: Bloaty initialization of two-register structs under
                    -Os on x86-64
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pskocik at gmail dot com
  Target Milestone: ---

When returning what should be simple two-register structs on x86-64,
gcc outputs really bloaty code under -Os when those registers are split into
multiple fields such as

int a,b,c,d;
OR
int a,b; long C;
OR
int a,b,c;

Here's some examples (which all should've been mov $-1, %eax; xor %edx, %edx;)
and what they compile to:

struct r4{ int a,b;long C; }; struct r4 r4(void){ return (struct r4){-1}; }
struct R4{ int a,b,c,d; }; struct R4 R4(void){ return (struct R4){-1}; }
struct r3{ int a,b,c; }; struct r3 r3(void){ return (struct r3){-1}; }



0000000000000000 <r4>:
   0:   be ff ff ff ff          mov    $0xffffffff,%esi
   5:   31 c9                   xor    %ecx,%ecx
   7:   31 c0                   xor    %eax,%eax
   9:   48 c1 e6 20             shl    $0x20,%rsi
   d:   48 21 f1                and    %rsi,%rcx
  10:   be ff ff ff ff          mov    $0xffffffff,%esi
  15:   89 c9                   mov    %ecx,%ecx
  17:   48 89 ca                mov    %rcx,%rdx
  1a:   48 89 c1                mov    %rax,%rcx
  1d:   48 09 f1                or     %rsi,%rcx
  20:   48 89 c8                mov    %rcx,%rax
  23:   c3                      ret    
sz$(r4)=36

0000000000000024 <R4>:
  24:   be ff ff ff ff          mov    $0xffffffff,%esi
  29:   31 c9                   xor    %ecx,%ecx
  2b:   31 c0                   xor    %eax,%eax
  2d:   48 c1 e6 20             shl    $0x20,%rsi
  31:   48 21 f1                and    %rsi,%rcx
  34:   be ff ff ff ff          mov    $0xffffffff,%esi
  39:   89 c9                   mov    %ecx,%ecx
  3b:   48 89 ca                mov    %rcx,%rdx
  3e:   48 89 c1                mov    %rax,%rcx
  41:   48 09 f1                or     %rsi,%rcx
  44:   48 89 c8                mov    %rcx,%rax
  47:   c3                      ret    
sz$(R4)=36

0000000000000048 <r3>:
  48:   31 c0                   xor    %eax,%eax
  4a:   c7 44 24 ec ff ff ff    movl   $0xffffffff,-0x14(%rsp)
  51:   ff 
  52:   48 89 44 24 f0          mov    %rax,-0x10(%rsp)
  57:   8b 4c 24 f4             mov    -0xc(%rsp),%ecx
  5b:   48 8b 44 24 ec          mov    -0x14(%rsp),%rax
  60:   48 89 ca                mov    %rcx,%rdx
  63:   c3                      ret    
sz$(r3)=28

-O2 fixes it except for r3 (that one's the least bothersome as padding a
register-returnable struct is no problem). `clang -Os` outputs `mov $-1, %eax;
xor %edx, %edx;` for each as expected.

https://godbolt.org/z/voxb5r9Gv

Reply via email to