https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126028
--- Comment #9 from Reshma Roy <Reshma.Roy at amd dot com> ---
(In reply to Richard Biener from comment #8)
> The testcase is now vectorized. What's missing is more optimal handling of
>
>
> pj_x_0 = p_1[jprev0].position.x; pj_x_1 = p_1[jprev1].position.x;
> pj_y_0 = p_1[jprev0].position.y; pj_y_1 = p_1[jprev1].position.y;
> ..
> for (;;)
> ...
> pj_x_0 = p_1[jprev0].position.x; pj_x_1 = p_1[jprev1].position.x;
> pj_y_0 = p_1[jprev0].position.y; pj_y_1 = p_1[jprev1].position.y;
>
> where the three vectors {pj_x_1, pj_x_0}, {pj_y_1, pj_y_0} and {pj_z_1,
> pj_z_0 }
> are constructed from scalar loads (because the vector SLP involves two
> distinct load groups). It's not clear whether two V2DF loads plus
> shuffling would be more efficient. I have a heuristic patch that moves
> the CTORs to the latch and the preheader instead of constructing from the
> PHI which removes an IV.
The code of interest in the test case as well as the namd benchmark is
vectorized in the latest gcc trunk. With the fix the loop vectorizes, i.e.,
packed vsubpd/vmulpd/vfmadd132pd instead of the fully scalar *sd codegen.
I created a standalone microbenchmark of this loop and there is a runtime
improvement with this vectorization. But the namd benchmark does not show any
measurable uplift. The remaining codegen caveat as you mentioned is that {pj_x,
pj_y, pj_z} are still built from scalar loads + vunpcklpd CTORs rather than two
V2DF loads plus a shuffle. Following your suggestion I hand-edited the kernel
to (with the understanding that this is what you intended):
vmovupd (%rax), %xmm4
vmovupd (%rdx), %xmm8
vpunpckhqdq %xmm8, %xmm4, %xmm5
vpunpcklqdq %xmm8, %xmm4, %xmm4
vmovsd 16(%rax), %xmm0
vmovhpd 16(%rdx), %xmm0, %xmm0
This binary was faster than the current generated binary. So, I think that two
V2DF loads plus shuffling is the better form here, it would be great if that
heuristic patch landed.