<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Missed optimization: bit-field struct with single byte enum class type."
   href="https://bugs.llvm.org/show_bug.cgi?id=45052">45052</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Missed optimization: bit-field struct with single byte enum class type.
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>9.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Common Code Generator Code
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>wnukowski@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>For a code


enum class enum_type8 : char { 
};
struct random_struct {
  enum_type8 field1: 8;
  char field2: 8;
};
bool Compare(const random_struct& lhs, const random_struct& rhs) {
  return lhs.field1 == rhs.field1 && lhs.field2 == rhs.field2;
};


llvm 9 (with -O2) emits: 


        movzx   eax, word ptr [rdi]
        movzx   ecx, word ptr [rsi]
        cmp     al, cl
        sete    dl
        xor     ecx, eax
        movzx   eax, cx
        cmp     eax, 256
        setb    al
        and     al, dl
        ret


But it could easily emit (as shown in compiler explorer link):


        movzx   eax, word ptr [rdi]
        cmp     ax, word ptr [rsi]
        sete    al
        ret


See <a href="https://godbolt.org/z/7CMja">https://godbolt.org/z/7CMja</a>-

In other words, optimizations are not able to handle the case of a struct with
bit-fields that contains single byte scoped enum. Making the enum type
'inherit' from short suddenly makes the optimizer happy, even when it does not
affect the layout of the struct (in this case { i16 }).

This is just a 'MVP' of a missed optimization. There are few other cases when
codegen behaves differently just because single byte scoped enum is present.
Another example when scoped enum size affects struct layout:

enum class test_enum8 : char {
};

enum class test_enum16 : short {
};

struct struct1 {

  bool field : 1;
  test_enum8 field2 : 8;
  char field3 : 7;
};

struct struct2 {

  bool field : 1;
  test_enum16 field2 : 8;
  char field3 : 7;
};

Results in:

%struct.struct1 = type <{ i8, i16 }>
%struct.struct2 = type { i16 }

But this could easily be packed as { i16 } in both cases. According to C++
standard, bit-field packing is implementation specific, so technically,
generated code is correct.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>