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

            Bug ID: 126793
           Summary: Store merging vs ivopts
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: enhancement
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ktkachov at gcc dot gnu.org
  Target Milestone: ---

/* The destination is an induction variable, so ivopts turns each store
   into a TARGET_MEM_REF with a different base pointer.  */

void
foo1 (__SIZE_TYPE__ n, unsigned char *p, const __UINT32_TYPE__ *src)
{
  for (__SIZE_TYPE__ i = 0; i < n; i++, p += 4)
    {
      __UINT32_TYPE__ w = src[i];
      p[0] = w;
      p[1] = w >> 8;
      p[2] = w >> 16;
      p[3] = w >> 24;
    }
}

/* Same through a global array, where the TARGET_MEM_REF has a symbol
   base.  */

unsigned char g[4096];

void
foo2 (__SIZE_TYPE__ n, const __UINT32_TYPE__ *src)
{
  for (__SIZE_TYPE__ i = 0; i < n; i++)
    {
      __UINT32_TYPE__ w = src[i];
      g[4 * i] = w;
      g[4 * i + 1] = w >> 8;
      g[4 * i + 2] = w >> 16;
      g[4 * i + 3] = w >> 24;
    }
}

on aarch64 GCC at -O2 generates:
foo1:
        cbz     x0, .L1
        lsl     x0, x0, 2
        add     x8, x1, 1
        add     x7, x1, 2
        add     x6, x1, 3
        mov     w3, 0
.L3:
        ldr     w4, [x2, x3]
        strb    w4, [x1, x3]
        lsr     w5, w4, 8
        strb    w5, [x8, x3]
        lsr     w5, w4, 16
        strb    w5, [x7, x3]
        lsr     w4, w4, 24
        strb    w4, [x6, x3]
        add     x3, x3, 4
        cmp     x0, x3
        bne     .L3
.L1:
        ret
foo2:
        cbz     x0, .L9
        adrp    x3, g
        add     x3, x3, :lo12:g
        mov     w4, 0
.L11:
        ldr     w2, [x1, x4, lsl 2]
        add     x4, x4, 1
        strb    w2, [x3]
        add     x3, x3, 4
        lsr     w5, w2, 8
        strb    w5, [x3, -3]
        lsr     w5, w2, 16
        lsr     w2, w2, 24
        strb    w5, [x3, -2]
        strb    w2, [x3, -1]
        cmp     x0, x4
        bne     .L11
.L9:
        ret
g:
        .zero   4096

I would have expected store merging to kick in, but because ivopts rewrites
loop memory references into TARGET_MEM_REFs the store merging pass doesn't
handle them.

Reply via email to