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.