https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82253

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |ice-on-valid-code
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2017-09-19
          Component|fortran                     |middle-end
     Ever confirmed|0                           |1

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
With -Og we end up with

  complex(kind=16) transfer.1;
  static integer(kind=1) zero[32] = {};
  complex(kind=16) obj;
  complex(kind=16) transfer.3_1;
  __complex__ uint128_t _4;

  <bb 2> [100.00%] [count: INV]:
  _4 = MEM[(c_char * {ref-all})&zero];
  MEM[(c_char * {ref-all})&transfer.1] = _4;
  transfer.3_1 = transfer.1;
  obj = transfer.3_1;
  transfer.1 ={v} {CLOBBER};

which ends up as

#2  0x0000000000b94512 in convert_mode_scalar (to=0x7ffff6a50bb8, 
    from=0x7ffff6a56018, unsignedp=1) at /tmp/trunk2/gcc/expr.c:280
280       scalar_mode from_mode = as_a <scalar_mode> (GET_MODE (from));
(gdb) p from
$1 = (rtx) 0x7ffff6a56018
(gdb) p debug_rtx (from)
(mem/u/c:CTI (reg/f:DI 96) [0 MEM[(c_char * {ref-all})&zero]+0 S32 A256])

as you see this is a complex mode, not a scalar one.  convert_move is called
with

(gdb) p debug_rtx (target)
(concat:TC (reg:TF 91 [ transfer.1 ])
    (reg:TF 92 [ transfer.1+16 ]))
$5 = void
(gdb) p debug_rtx (temp)
(mem/u/c:CTI (reg/f:DI 96) [0 MEM[(c_char * {ref-all})&zero]+0 S32 A256])

but convert_move isn't prepared to handle this kind of move.

With -O1 we expand from the simpler

  __complex__ uint128_t _24;
  complex(kind=16) _26;

  <bb 2> [100.00%] [count: INV]:
  _24 = MEM[(c_char * {ref-all})&zero];
  _26 = VIEW_CONVERT_EXPR<complex(kind=16)>(_24);
  obj = _26;

this "transform" requires two FRE pass instances as in the first we are
presented with

  parm.0.data = &zero[0];
  parm.0.offset = -1;
  _3 = parm.0.dim[0].ubound;
  _4 = parm.0.dim[0].lbound;
  _23 = _3 - _4;
  _5 = _23 + 1;
  _6 = MIN_EXPR <_5, 32>;
  _7 = MAX_EXPR <_6, 0>;
  _8 = (unsigned long) _7;
  _9 = parm.0.data;
  __builtin_memcpy (&transfer.1, _9, _8);
  transfer.3_10 = transfer.1;
  obj = transfer.3_10;

which gets optimized to

  _22 = MEM[(c_char * {ref-all})&zero];
  MEM[(c_char * {ref-all})&transfer.1] = _22;
  transfer.3_10 = transfer.1;

only during folding of the memcpy during elimination of the first pass.  We
do not expose the memcpy result in the VN hashtable when looking through it
(not sure if that would be easily possible).

Reply via email to