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

            Bug ID: 109246
           Summary: Missed optimization for 2-dimensional array with equal
                    values accessed through Enums
           Product: gcc
           Version: 12.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: andre.schackier at gmail dot com
  Target Milestone: ---

Given the following code:

enum class E {
    A = 0,
    B = 1,
};

constexpr int t[2][2]{{1, 1}, {1, 1}};

int f1(E a) { return t[static_cast<int>(a)][static_cast<int>(a)]; }

int f2(E a, E b) { return t[static_cast<int>(a)][static_cast<int>(b)]; }

and compiling with '-O3 -fstrict-enums' gives:
- https://godbolt.org/z/s8jssnqq5

f1(E):
        movsx   rdi, edi
        lea     rax, [rdi+rdi*2]
        mov     eax, DWORD PTR t[0+rax*4]
        ret
f2(E, E):
        movsx   rsi, esi
        movsx   rdi, edi
        lea     rax, [rsi+rdi*2]
        mov     eax, DWORD PTR t[0+rax*4]
        ret
t:
        .long   1
        .long   1
        .long   1
        .long   1

gcc should be able to determine that in all cases both 'f1' and 'f2' can only
ever return 1.

The same is happening for
3x3 - https://godbolt.org/z/7v7hfq357
4x4 - https://godbolt.org/z/fTejK8YKb
5x5 - https://godbolt.org/z/31GcKPG6c
arrays.

Also explicitly telling the compiler about the valid values for 'a' and 'b'
using '__builtin_unreachable()' like this:

enum class E {
    A = 0,
    B = 1,
};

constexpr int t[2][2]{{1, 1}, {1, 1}};

int f1(E a) {
    if (a != E::A && a != E::B) {
        __builtin_unreachable();
    }

    return t[static_cast<int>(a)][static_cast<int>(a)];
}

int f2(E a, E b) {
    if (a != E::A && a != E::B) {
        __builtin_unreachable();
    }
    if (b != E::A && b != E::B) {
        __builtin_unreachable();
    }

    return t[static_cast<int>(a)][static_cast<int>(b)];
}

does not help - https://godbolt.org/z/6x7xKo1xj

Reply via email to