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;
}

Reply via email to