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

            Bug ID: 126099
           Summary: BB vectorization SLP subgraphs are not merged
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rguenth at gcc dot gnu.org
  Target Milestone: ---

void foo (long *p, long *q, long *r)
{
  long tem0 = r[0];
  long tem1 = r[1];
  long tem2 = r[2];
  long tem3 = r[3];
  tem0 = tem0 + 1;
  tem1 = tem1 + 2;
  tem2 = tem2 + 3;
  tem3 = tem3 + 4;
  p[0] = tem0;
  p[1] = tem1;
  q[0] = tem0;
  q[1] = tem1;
  q[2] = tem2;
  q[3] = tem3;
}

we perform discovery from the p[] and q[] stores, ending up with redundant
lanes in both subgraphs (which we cost together because of that overlap):

t.c:13:8: note: Costing subgraph: 
t.c:13:8: note: node 0x4f5e550 (max_nunits=2, refcnt=1) vector(2) long int
t.c:13:8: note: op template: *p_11(D) = tem0_7;
t.c:13:8: note:         stmt 0 *p_11(D) = tem0_7;
t.c:13:8: note:         stmt 1 MEM[(long int *)p_11(D) + 8B] = tem1_8;
t.c:13:8: note:         children 0x4f5e600
t.c:13:8: note: node 0x4f5e600 (max_nunits=2, refcnt=1) vector(2) long int
t.c:13:8: note: op template: tem0_7 = tem0_3 + 1;
t.c:13:8: note:         stmt 0 tem0_7 = tem0_3 + 1;
t.c:13:8: note:         stmt 1 tem1_8 = tem1_4 + 2;
t.c:13:8: note:         children 0x4f5e6b0 0x4f5e760
t.c:13:8: note: node 0x4f5e6b0 (max_nunits=2, refcnt=1) vector(2) long int
t.c:13:8: note: op template: tem0_3 = *r_2(D);
t.c:13:8: note:         stmt 0 tem0_3 = *r_2(D);
t.c:13:8: note:         stmt 1 tem1_4 = MEM[(long int *)r_2(D) + 8B];
t.c:13:8: note: node (constant) 0x4f5e760 (max_nunits=1, refcnt=1) vector(2)
long int
t.c:13:8: note:         { 1, 2 }
t.c:13:8: note: node 0x4f5e810 (max_nunits=2, refcnt=1) vector(2) long int
t.c:13:8: note: op template: *q_14(D) = tem0_7;
t.c:13:8: note:         stmt 0 *q_14(D) = tem0_7;
t.c:13:8: note:         stmt 1 MEM[(long int *)q_14(D) + 8B] = tem1_8;
t.c:13:8: note:         stmt 2 MEM[(long int *)q_14(D) + 16B] = tem2_9;
t.c:13:8: note:         stmt 3 MEM[(long int *)q_14(D) + 24B] = tem3_10;
t.c:13:8: note:         children 0x4f5e8c0
t.c:13:8: note: node 0x4f5e8c0 (max_nunits=2, refcnt=1) vector(2) long int
t.c:13:8: note: op template: tem0_7 = tem0_3 + 1;
t.c:13:8: note:         stmt 0 tem0_7 = tem0_3 + 1;
t.c:13:8: note:         stmt 1 tem1_8 = tem1_4 + 2;
t.c:13:8: note:         stmt 2 tem2_9 = tem2_5 + 3;
t.c:13:8: note:         stmt 3 tem3_10 = tem3_6 + 4;
t.c:13:8: note:         children 0x4f5e970 0x4f5ea20
t.c:13:8: note: node 0x4f5e970 (max_nunits=2, refcnt=1) vector(2) long int
t.c:13:8: note: op template: tem0_3 = *r_2(D);
t.c:13:8: note:         stmt 0 tem0_3 = *r_2(D);
t.c:13:8: note:         stmt 1 tem1_4 = MEM[(long int *)r_2(D) + 8B];
t.c:13:8: note:         stmt 2 tem2_5 = MEM[(long int *)r_2(D) + 16B];
t.c:13:8: note:         stmt 3 tem3_6 = MEM[(long int *)r_2(D) + 24B];
t.c:13:8: note: node (constant) 0x4f5ea20 (max_nunits=1, refcnt=1) vector(2)
long int
t.c:13:8: note:         { 1, 2, 3, 4 }

so we do not realize we could perform the p[] store from extracting the
lowpart of the node 0x4f5e8c0 vector.

On x86 with -mavx2 nothing fixes this up (it ends up overall profitable still):

foo:
.LFB0:
        .cfi_startproc
        vmovdqa .LC0(%rip), %ymm0
        vmovdqa .LC1(%rip), %xmm1
        vpaddq  (%rdx), %ymm0, %ymm0
        vpaddq  (%rdx), %xmm1, %xmm1
        vmovdqu %xmm1, (%rdi)
        vmovdqu %ymm0, (%rsi)
        vzeroupper
        ret

where the vpaddq to %xmm1 could be removed and the store be done from %xmm0.

Reply via email to