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

            Bug ID: 98142
           Summary: fstrict-enums optimization applied only for unscoped
                    enums with unfixed underlying type
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: barry.revzin at gmail dot com
  Target Milestone: ---

Consider this simple example

namespace N4 {
enum E {
    A, B, C, D
};

bool compare_logical(E x) { return (x == E::B) || (x == E::D); }
}

Compiled with -O3 -fstrict-enums, gcc 10.2 emits:

N4::compare_logical(N4::E):
        mov     eax, edi
        and     eax, 1
        ret

As desired. I am telling gcc to make an assumption about the range of values,
and it is optimizing based on the fact that 5 is not a valid enumerator.
Fantastic.

However, any other definition of E, whether it's scoped:

enum class E {
    A, B, C, D
};

Or it has a fixed underlying type:

enum E : unsigned {
    A, B, C, D
};

or both:

enum class E : unsigned {
    A, B, C, D
};

in all cases emits the same alternative code:

N3::compare_logical(N3::E):
        and     edi, -3
        cmp     edi, 1
        sete    al
        ret

It does this extra work to be able to reject, for instance, the value 5. But
I'm trying to tell the optimizer that this does not happen.

Full example on compiler explorer: https://godbolt.org/z/Tq58hK

Can this optimization be extended to cover these additional cases, or is there
some reason it cannot?

Reply via email to