[llvm-bugs] [Bug 45052] New: Missed optimization: bit-field struct with single byte enum class type.

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Feb 27 15:22:17 PST 2020


https://bugs.llvm.org/show_bug.cgi?id=45052

            Bug ID: 45052
           Summary: Missed optimization: bit-field struct with single byte
                    enum class type.
           Product: libraries
           Version: 9.0
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Common Code Generator Code
          Assignee: unassignedbugs at nondot.org
          Reporter: wnukowski at google.com
                CC: llvm-bugs at lists.llvm.org

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 https://godbolt.org/z/7CMja-

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.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200227/1a353f58/attachment.html>


More information about the llvm-bugs mailing list