https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99470
Bug ID: 99470 Summary: Convert fixed index addition to array address offset Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: redbeard0531 at gmail dot com Target Milestone: --- These two functions do the same thing but f() is the cleaner source code (especially when arr is a std::array) while g() generates better code: https://gcc.godbolt.org/z/vTT399 #include <cstdint> inline int8_t arr[256]; bool f(int a, int b) { return arr[a+128] == arr[b+128]; } bool g(int a, int b) { return (arr+128)[a] == (arr+128)[b]; } f(int, int): sub edi, -128 sub esi, -128 lea rax, arr[rip] movsx rdi, edi movsx rsi, esi movzx edx, BYTE PTR [rax+rsi] cmp BYTE PTR [rax+rdi], dl sete al ret g(int, int): lea rax, arr[rip+128] movsx rdi, edi movsx rsi, esi movzx edx, BYTE PTR [rax+rsi] cmp BYTE PTR [rax+rdi], dl sete al ret In addition to only doing the +128 once, it also ends up being completely free in g() because the assembler (or linker?) folds the addition into the address calculation by adjusting the offset of the rip-relative address. In the godbolt link, you can see that when compiled to binary, the LEA instruction uses the same form in both f() and g(), so the addition really is free in g().