https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128431
--- Comment #3 from Thomas Koenig <tkoenig at gcc dot gnu.org> ---
This equivalent C code
#include <stdint.h>
#include <string.h>
#define GRPSZ 6
#define TABSZ 729
#define N_GRP 6
#define HALFSIZE (N_GRP * GRPSZ)
extern const unsigned char tab[TABSZ][GRPSZ];
void foo(unsigned long from_small, unsigned long to_small,
unsigned char *restrict from_buf, unsigned char *restrict to_buf)
{
const unsigned long tabszu = TABSZ;
for (int i = 0; i < HALFSIZE; i += GRPSZ)
{
unsigned long to_rem, from_rem;
to_rem = to_small % tabszu;
to_small /= tabszu;
from_rem = from_small % tabszu;
from_small /= tabszu;
memcpy(to_buf + i, tab[to_rem], GRPSZ);
memcpy(from_buf + i, tab[from_rem], GRPSZ);
}
}
generates something that looks reasonable:
movl tab(%rsi), %edx
movl %edx, -6(%rax)
movzwl tab+4(%rsi), %edx
subq %rbx, %rcx
leaq (%rcx,%rcx,2), %rcx
movw %dx, -2(%rax)
addq %rcx, %rcx
movl tab(%rcx), %edx
movl %edx, -6(%rdi)
movzwl tab+4(%rcx), %edx
movw %dx, -2(%rdi)
Maybe recognizing the array assignment as a memcpy would work.
The front end could also emit that if the array slices are simply contiguous
(as is the case here), but that would not solve the issue for a C case
which uses a for loop.