https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127647
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
-reflectionvec.fppized.f90:972:48: optimized: basic block part vectorized using
8 byte vectors
is previously vectorized as
vect__8.1811_56 = MEM <vector(2) integer(kind=4)> [(integer(kind=4)
*)vectp.1810_45];
_50 = BIT_FIELD_REF <vect__8.1811_56, 32, 32>;
_51 = BIT_FIELD_REF <vect__8.1811_56, 32, 0>;
vectp.1810_54 = vectp.1810_45 + 4;
_8 = *_7.h;
_9 = *_7.k;
MEM <vector(2) integer(kind=4)> [(integer(kind=4) *)&A.230] =
vect__8.1811_56;
_10 = *_7.l;
MEM[(integer(kind=4) *)&A.230 + 8B] = _10;
if (stride.222_17 != 1)
goto <bb 17>; [20.00%]
else
goto <bb 16>; [80.00%]
<bb 17> [local count: 53687090]:
MEM[(integer(kind=4) *)__result.0_27] = _51;
_20 = stride.222_17 * 4;
_19 = (sizetype) _20;
_52 = __result.0_27 + _19;
*_52 = _50;
_12 = stride.222_17 * 2;
_13 = _12 * 4;
_14 = (sizetype) _13;
_15 = __result.0_27 + _14;
*_15 = _10;
goto <bb 8>; [100.00%]
<bb 16> [local count: 214748366]:
__builtin_memcpy (__result.0_27, &A.230, 12);
and now not anymore:
_8 = *_7.h;
MEM[(integer(kind=4) *)&A.230] = _8;
_9 = *_7.k;
MEM[(integer(kind=4) *)&A.230 + 4B] = _9;
_10 = *_7.l;
MEM[(integer(kind=4) *)&A.230 + 8B] = _10;
if (stride.222_17 != 1)
goto <bb 17>; [20.00%]
else
goto <bb 16>; [80.00%]
<bb 17> [local count: 53687090]:
MEM[(integer(kind=4) *)__result.0_27] = _8;
_20 = stride.222_17 * 4;
_19 = (sizetype) _20;
_52 = __result.0_27 + _19;
*_52 = _9;
_12 = stride.222_17 * 2;
_13 = _12 * 4;
_14 = (sizetype) _13;
_15 = __result.0_27 + _14;
*_15 = _10;
goto <bb 8>; [100.00%]
<bb 16> [local count: 214748366]:
__builtin_memcpy (__result.0_27, &A.230, 12);
and we expand the memcpy to use 8 byte + 4 byte moves, hitting STLF fail.
Vectorizing the store mitigates that.
│ mov %ecx,-0xc(%rsp)
▒
487 │ mov %edx,-0x8(%rsp)
▒
│ mov %eax,-0x4(%rsp)
▒
│ cmp $0x1,%r8
▒
│ jne a0
▒
│ mov -0xc(%rsp),%rax
▒
8312 │ mov %rax,(%rsi)
▒
1373 │ mov -0x4(%rsp),%eax
▒
8517 │ mov %eax,0x8(%rsi)
vector code:
5 │ vmovq (%rax),%xmm0
9 │ mov 0x8(%rax),%eax
│ vmovq %xmm0,-0x10(%rsp)
183 │ cmp $0x1,%rdx
│ jne 60
│ mov -0x10(%rsp),%rdx
12 │ mov %eax,0x8(%rsi)
829 │ mov %rdx,(%rsi)
where we also somehow managed to eliminate half of the stack storages. The
vector extract part is never hit:
│60: vmovd %xmm0,(%rsi)
│ vpextrd $0x1,%xmm0,(%rsi,%rdx,4)
│ mov %eax,(%rsi,%rdx,8)
the fortran source for this function is:
pure function indices(self,n) result(res)
type(reflection_type), dimension(:) :: self
! Return the miller indices of reflection n.
intent(in) :: self
integer(kind=kind(1)), intent(in) :: n
integer(kind=kind(1)), dimension(3) :: res
res = (/ self(n)%h, self(n)%k, self(n)%l /)
end function
the actual cost modeling is sensible, what we lack is seeing that we
eventually only store the result to memory.
Also there's missed store sinking happening, I'm going to address that.