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

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
-fast_algorithms.c:165:19: optimized: loop vectorized using 16 byte vectors and
unroll factor 4
-msa.c:160:18: optimized: basic block part vectorized using 8 byte vectors

is all of the (vectorization) difference.

The first loop is

    for (k = 1; k <= hmm->M; k++)
      if ((sc =  mpc[k] + ep[k]) > xme) xme = sc;
    xmx[i][XME] = xme;

a conditional reduction.  The second is just

  msa->nseqalloc += msa->nseqlump;

that's very unlikely the issue.

For the first a testcase that actually regresses is

int foo (int *mpc, int *ep, int M)
{
  int xme = -987654321;
  for (int k = 1; k < M; k++)
    {
      int sc;
      if ((sc = mpc[k] + ep[k]) > xme)
        xme = sc;
    }
  return xme;
}

and we have

@@ -290,7 +290,7 @@
 _4 + _7 1 times vector_stmt costs 4 in body
 MAX_EXPR <sc_14, xme_18> 1 times scalar_to_vec costs 4 in prologue
 MAX_EXPR <sc_14, xme_18> 1 times vector_stmt costs 16 in epilogue
-MAX_EXPR <sc_14, xme_18> 1 times vec_to_scalar costs 4 in epilogue
+MAX_EXPR <sc_14, xme_18> 1 times vec_to_scalar costs 16 in epilogue
 MAX_EXPR <sc_14, xme_18> 1 times vector_stmt costs 16 in body
 t.c:4:21: note:  operating on full vectors.
 t.c:4:21: note:  epilog loop required
@@ -307,16 +307,18 @@
 t.c:4:21: note:  Cost model analysis: 
   Vector inside of loop cost: 44
   Vector prologue cost: 4
-  Vector epilogue cost: 108
+  Vector epilogue cost: 120
   Scalar iteration cost: 36
   Scalar outside cost: 32
-  Vector outside cost: 112
+  Vector outside cost: 124
   prologue iterations: 0
   epilogue iterations: 2
   Calculated minimum iters for profitability: 3
 t.c:4:21: note:    Runtime profitability threshold = 4
-t.c:4:21: note:    Static estimate profitability threshold = 4
-t.c:4:21: note:  ***** Analysis succeeded with vector mode V4SI
+t.c:4:21: note:    Static estimate profitability threshold = 5
+t.c:4:21: missed:  one iteration of the vector loop would be more expensive
than the equivalent number of iterations of the scalar loop
+t.c:4:21: missed:  Loop costings not worthwhile.
+t.c:4:21: note:  ***** Analysis failed with vector mode V4SI

which is because of

  /* If the vector loop needs multiple iterations to be beneficial then
     things are probably too close to call, and the conservative thing
     would be to stick with the scalar code.  */
  if (loop_cost_model (loop) == VECT_COST_MODEL_VERY_CHEAP
      && min_profitable_estimate > (int) vect_vf_for_cost (loop_vinfo))
    {
      if (dump_enabled_p ())
        dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
                         "one iteration of the vector loop would be"
                         " more expensive than the equivalent number of"
                         " iterations of the scalar loop\n");
      return 0;
    }

The actual generated code is

.L4:
        movdqu  4(%rdi,%rax), %xmm0
        movdqu  4(%rsi,%rax), %xmm3
        addq    $16, %rax
        paddd   %xmm3, %xmm0
        movdqa  %xmm0, %xmm1
        pcmpgtd %xmm2, %xmm1
        pand    %xmm1, %xmm0
        pandn   %xmm2, %xmm1
        movdqa  %xmm1, %xmm2
        por     %xmm0, %xmm2
        cmpq    %rcx, %rax
        jne     .L4
        movdqa  %xmm2, %xmm0
        sall    $2, %edx
        psrldq  $8, %xmm0
        movdqa  %xmm0, %xmm1
        pcmpgtd %xmm2, %xmm1
        pand    %xmm1, %xmm0
        pandn   %xmm2, %xmm1
        por     %xmm0, %xmm1
        movdqa  %xmm1, %xmm2
        psrldq  $4, %xmm2
        movdqa  %xmm2, %xmm0
        pcmpgtd %xmm1, %xmm0
        pand    %xmm0, %xmm2
        pandn   %xmm1, %xmm0
        por     %xmm2, %xmm0
        movd    %xmm0, %ecx  -> the vect_to_scalar
        cmpl    %edx, %r9d
        je      .L1 -> skip scalar epilog
        addl    $1, %edx
.L3:
        movl    %edx, %eax
.L5:
        movl    (%rsi,%rax,4), %edx
        addl    (%rdi,%rax,4), %edx
        cmpl    %edx, %ecx
        cmovl   %edx, %ecx
        addq    $1, %rax
        cmpl    %eax, %r8d
        jg      .L5
.L1:
        movl    %ecx, %eax
        ret

I believe the assessment that when there's only a single vector iteration
(so M in [6, 8]) the whole sequence is slower than iterating the scalar
loop is probably true.  In reality the loop iterates much more often,
but -O2 with the VERY_CHEAP cost model erors on the conservative side.

Now, the spec code stores the reduction result in memory which you
might argue we don't need the XMM -> GPR penalty, but as we have to
dispatch to the scalar epilog we do.  With -msse4 the MAX becomes cheaper
(pmaxsd) and we vectorize it at -O2 again.

So I think it works as designed for -O2.  We don't know the loop iterates
(many) more times w/o PGO.

Reply via email to