[PATCH] Fix ICE during MEM_REF expansion (PR middle-end/90840)

Eric Botcazou ebotcazou@adacore.com
Sat Dec 7 12:21:00 GMT 2019


> On the following testcase we ICE on i686-linux (32-bit), because we store
> (first 96-bit, then 72-bit) structure into the first part of a 2x 96-bit
> complex long double, and for 96-bit floats there is no corresponding
> integral mode that covers it and we ICE when op0 is not in MEM (it is a
> REG).

The test triggers an ICE in simplify_subreg because the innermode is BLKmode:

  gcc_assert (innermode != BLKmode);

on PowerPC64/VxWorks at -O1 and above.  This comes from this call:

		  if (MEM_P (result))
 		    from_rtx = change_address (result, to_mode, NULL_RTX);
 		  else
 		    from_rtx
		      = simplify_gen_subreg (to_mode, result,
					     TYPE_MODE (TREE_TYPE (from)), 0);

in expand_assignment, where 'result' is not a MEM despite TREE_TYPE (from) 
having BLKmode.  That's as expected because 'from' is a CALL_EXPR whose result 
is returned as a TImode register to avoid using BLKmode and thus spilling it 
to memory in between.

It turns out that simplify_subreg contains another assertion:

  gcc_assert (GET_MODE (op) == innermode
	      || GET_MODE (op) == VOIDmode);

so we can equivalently pass GET_MODE (result) as the mode, except when it is 
VOIDmode in which case we can still use TYPE_MODE (TREE_TYPE (from)).

Tested on PowerPC64/VxWorks and x86-64/Linux, applied on mainline as obvious.


2019-12-07  Eric Botcazou  <ebotcazou@adacore.com>

	PR middle-end/90840
	* expr.c (expand_assignment): In the case of a CONCAT on the LHS, make
	sure to pass a valid inner mode in calls to simplify_gen_subreg.

-- 
Eric Botcazou
-------------- next part --------------
A non-text attachment was scrubbed...
Name: p.diff
Type: text/x-patch
Size: 1298 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20191207/6d3886ff/attachment.bin>


More information about the Gcc-patches mailing list