This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug middle-end/77295] New: missed optimisation when copying/moving union members


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

            Bug ID: 77295
           Summary: missed optimisation when copying/moving union members
           Product: gcc
           Version: 6.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: avi@cloudius-systems.com
  Target Milestone: ---

Discriminated unions of class types are becoming popular; for example
std::variant<...> or std::future<T>.

gcc doesn't optimize copies or moved of discriminated unions well:


// Will usually be a template with user-defined types
// as members of the union
struct discriminated_union {
  unsigned which;
  union {
    int v1;
    long v2;
  };
  discriminated_union(discriminated_union&&);
};

discriminated_union::discriminated_union(discriminated_union&& x) {
  which = x.which;
  switch (x.which) {
  case 1:
    v1 = x.v1;
    break;
  case 2:
    v2 = x.v2;
    break;
  }
}


compiles into

   0:   8b 06                   mov    (%rsi),%eax
   2:   89 07                   mov    %eax,(%rdi)
   4:   8b 06                   mov    (%rsi),%eax
   6:   83 f8 01                cmp    $0x1,%eax
   9:   74 1d                   je     28
<discriminated_union::discriminated_union(discriminated_union&&)+0x28>
   b:   83 f8 02                cmp    $0x2,%eax
   e:   75 10                   jne    20
<discriminated_union::discriminated_union(discriminated_union&&)+0x20>
  10:   48 8b 46 08             mov    0x8(%rsi),%rax
  14:   48 89 47 08             mov    %rax,0x8(%rdi)
  18:   c3                      retq   
  19:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)
  20:   f3 c3                   repz retq 
  22:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
  28:   8b 46 08                mov    0x8(%rsi),%eax
  2b:   89 47 08                mov    %eax,0x8(%rdi)
  2e:   c3                      retq   

instead of just copying the 12 bytes from (%rsi) into (rdi); unconditionally
copying the long is cheaper than the branching.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]