On 10/28/2016 01:25 AM, Richard Biener wrote:
On Thu, 27 Oct 2016, Jakub Jelinek wrote:

Hi!

The following testcase ICEs on x86_64-linux with -O1, the problem is
that we expand assignment from COMPONENT_REF of MEM_REF into a V4SImode
SSA_NAME.  The MEM_REF has non-addressable DCmode var inside of it, and
type of a struct containing a single V4SImode element.

The bug seems to be that if the op0 (i.e. get_inner_reference expanded)
is a CONCAT and we want a reference that covers all bits of the CONCAT,
we just short path it and return it immediately, rather than trying
to convert it to the requested mode.

I've bootstrapped/regtested on x86_64-linux and i686-linux the following
patch, which takes the short path only if we want a complex mode.
The only place it makes a difference in both bootstraps/regtests was this
new testcase.

Though, perhaps COMPLEX_MODE_P (mode1) is also wrong, if mode1 isn't
GET_MODE (op0), then we still will return something with unexpected mode
(e.g. DCmode vs. CDImode); I wonder if for such mismatches we shouldn't
just force_reg (convert_modes ()) each CONCAT operand separately and
create a new CONCAT.  Do we have a guarantee that COMPLEX_MODE_P (GET_MODE 
(op0))
if op0 is CONCAT?

I think so.  I'll leave the rest to people more familiar with RTL
expansion -- generally I thought the callers of expand() have to deal
with expansions that return a different mode?
You generally have to deal with expansions that return the object in a new pseudo instead of the one you asked for -- so the caller has to test for that and emit a copy when it happens.

I don't offhand recall cases where we have to deal with getting a result in a different mode than was asked. But given the history of the expanders, I wouldn't be surprised if there's oddball cases where that can happen.

jeff


Reply via email to