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.

Reply via email to