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).