https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128218
--- Comment #7 from Steve Kargl <kargl at gcc dot gnu.org> ---
(In reply to Henri Menke from comment #6)
> (In reply to Harald Anlauf from comment #4)
> > Can you try a different size (like double or half the size)?
>
> I guess you mean use real(4) and complex(4) instead of real(8) and
> complex(8). No, there is not substantial difference. The generated code
> remains chaotic in 16.2.1.
>
> On top of that when I change integer(8) to integer(4) the generated code
> becomes even more chaotic. The following 32-bit example also still trips up
> 17.0.0:
>
Removing z2 part leaves code that still shows the problem.
subroutine g(a, e, z1)
real, intent(in) :: a(*)
integer, value :: e
complex, intent(out) :: z1
z1 = transfer(a(e:e+1), z1) ! cmplx(a(e), a(e+1))
end subroutine
The -fdump-tree-original and -fdump-tree-optimized look
reasonable to me. Here's, the former where I've compressed
declarations to a single line where possible and wrapped
long lines
__attribute__((fn spec (". r w w ")))
void g (real(kind=4)[0:] * restrict a, integer(kind=4) e,
complex(kind=4) & restrict z1)
{
{
integer(kind=8) D.4790, D.4791, D.4792, D.4809, D.4810, D.4811;
struct array01_real(kind=4) parm.0;
complex(kind=4) transfer.1;
D.4791 = (integer(kind=8)) e;
D.4792 = (integer(kind=8)) (e + 1);
parm.0.span = 4;
parm.0.dtype = {.elem_len=4, .version=0, .rank=1, .type=3};
parm.0.dim[0].lbound = 1;
parm.0.dim[0].ubound = (1 - D.4791) + D.4792;
parm.0.dim[0].stride = 1;
parm.0.data = (void *) &(*a)[D.4791 + -1];
parm.0.offset = -1;
D.4790 = 4;
D.4809 = parm.0.dim[0].ubound - parm.0.dim[0].lbound;
D.4790 = (D.4809 + 1) * D.4790;
D.4810 = 8;
__builtin_memcpy ((void *) &transfer.1, parm.0.data,
(unsigned long) MAX_EXPR <MIN_EXPR <D.4810, D.4790>, 0>);
*z1 = transfer.1;
}
}
and here's the latter
;; Function g (g_, funcdef_no=0, decl_uid=4785, cgraph_uid=1, symbol_order=0)
__attribute__((fn spec (". r w w ")))
void g (real(kind=4)[0:] * restrict a, integer(kind=4) e,
complex(kind=4) & restrict z1)
{
vector(2) real(kind=4) vect__20.11;
complex(kind=4) transfer.1;
integer(kind=4) _1;
integer(kind=8) _2, _3, _4, _6, _7, _11, _12, _15;
real(kind=4) * _5;
unsigned long _8;
sizetype _9, _23;
<bb 2> [local count: 1073741824]:
_11 = (integer(kind=8)) e_10(D);
_1 = e_10(D) + 1;
_12 = (integer(kind=8)) _1;
_2 = 1 - _11;
_3 = _2 + _12;
_4 = _11 + -1;
_9 = (sizetype) _4;
_23 = _9 * 4;
_5 = a_14(D) + _23;
_15 = _3 * 4;
_6 = MIN_EXPR <_15, 8>;
_7 = MAX_EXPR <_6, 0>;
_8 = (unsigned long) _7;
__builtin_memcpy (&transfer.1, _5, _8);
vect__20.11_24 = MEM <vector(2) real(kind=4)> [(real(kind=4) *)&transfer.1];
MEM <vector(2) real(kind=4)> [(real(kind=4) *)z1_17(D)] = vect__20.11_24;
transfer.1 ={v} {CLOBBER(eos)};
return;
}