This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix expansion issues on type changing MEM_REFs on LHS (PR middle-end/48335)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Eric Botcazou <ebotcazou at adacore dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 1 Apr 2011 13:29:43 +0200
- Subject: Re: [PATCH] Fix expansion issues on type changing MEM_REFs on LHS (PR middle-end/48335)
- References: <20110330160546.GP18914@tyan-ft48-01.lab.bos.redhat.com> <201104011252.04323.ebotcazou@adacore.com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Fri, Apr 01, 2011 at 12:52:04PM +0200, Eric Botcazou wrote:
> > --- gcc/expr.c.jj 2011-03-23 17:15:55.000000000 +0100
> > +++ gcc/expr.c 2011-03-30 11:38:15.000000000 +0200
> > @@ -4278,16 +4278,47 @@ expand_assignment (tree to, tree from, b
> > /* Handle expand_expr of a complex value returning a CONCAT. */
> > else if (GET_CODE (to_rtx) == CONCAT)
> > {
> > - if (COMPLEX_MODE_P (TYPE_MODE (TREE_TYPE (from))))
> > + unsigned short mode_bitsize = GET_MODE_BITSIZE (GET_MODE (to_rtx));
> > + if (COMPLEX_MODE_P (TYPE_MODE (TREE_TYPE (from)))
> > + && bitpos == 0
> > + && bitsize == mode_bitsize)
> > + result = store_expr (from, to_rtx, false, nontemporal);
> > + else if (bitsize == mode_bitsize / 2
> > + && (bitpos == 0 || bitpos == GET_MODE_BITSIZE (mode1)))
> > + result = store_expr (from, XEXP (to_rtx, bitpos != 0), false,
> > + nontemporal);
>
> Why GET_MODE_BITSIZE (mode1) and not mode_bitsize / 2 here?
It should be mode_bitsize / 2 yeah, GET_MODE_BITSIZE (mode1) just came
from the original code. Will change.
> > {
> > - gcc_assert (bitpos == 0 || bitpos == GET_MODE_BITSIZE (mode1));
> > - result = store_expr (from, XEXP (to_rtx, bitpos != 0), false,
> > - nontemporal);
> > + rtx temp = assign_stack_temp (GET_MODE (to_rtx),
> > + GET_MODE_SIZE (GET_MODE (to_rtx)),
> > + 0);
> > + write_complex_part (temp, XEXP (to_rtx, 0), false);
> > + write_complex_part (temp, XEXP (to_rtx, 1), true);
> > + result = store_field (temp, bitsize, bitpos, mode1, from,
> > + TREE_TYPE (tem), get_alias_set (to),
> > + nontemporal);
> > + emit_move_insn (XEXP (to_rtx, 0), read_complex_part (temp, false));
> > + emit_move_insn (XEXP (to_rtx, 1), read_complex_part (temp, true));
> > }
>
> Can't you add result = NULL at the end of the block?
result is set there from store_field, and result is only used in
if (result)
preserve_temp_slots (result);
afterwards. store_field might want to preserve_temp_slots perhaps, so
clearing result afterwards might be wrong.
> > : (! SLOW_UNALIGNED_ACCESS (fieldmode, MEM_ALIGN (op0))
> > :
> > || (offset * BITS_PER_UNIT % bitsize == 0
> >
> > - && MEM_ALIGN (op0) % GET_MODE_BITSIZE (fieldmode) == 0))))
> > + && MEM_ALIGN (op0) % GET_MODE_BITSIZE (fieldmode) == 0)))
> > + && (MEM_P (op0)
> > + || GET_MODE (op0) == fieldmode
> > + || validate_subreg (fieldmode, GET_MODE (op0), op0, byte_offset)))
>
> This partially duplicates the existing test. Can't the new code be retrofitted
> into the existing test?
You mean just with the MEM_P test? So something like:
@@ -418,8 +418,11 @@ store_bit_field_1 (rtx str_rtx, unsigned
&& bitsize == GET_MODE_BITSIZE (fieldmode)
&& (!MEM_P (op0)
? ((GET_MODE_SIZE (fieldmode) >= UNITS_PER_WORD
- || GET_MODE_SIZE (GET_MODE (op0)) == GET_MODE_SIZE (fieldmode))
- && byte_offset % GET_MODE_SIZE (fieldmode) == 0)
+ || GET_MODE_SIZE (GET_MODE (op0)) == GET_MODE_SIZE (fieldmode))
+ && byte_offset % GET_MODE_SIZE (fieldmode) == 0
+ && (GET_MODE (op0) == fieldmode
+ || validate_subreg (fieldmode, GET_MODE (op0), op0,
+ byte_offset)))
: (! SLOW_UNALIGNED_ACCESS (fieldmode, MEM_ALIGN (op0))
|| (offset * BITS_PER_UNIT % bitsize == 0
&& MEM_ALIGN (op0) % GET_MODE_BITSIZE (fieldmode) == 0))))
instead?
> > /* OFFSET is in UNITs, and UNIT is in bits.
> > - store_fixed_bit_field wants offset in bytes. */
> > - store_fixed_bit_field (word, offset * unit / BITS_PER_UNIT,
> > thissize, - thispos, part);
> > + store_fixed_bit_field wants offset in bytes. If WORD is const0_rtx,
> > + it is jut an out of bounds access. Ignore it. */
> > + if (word != const0_rtx)
> > + store_fixed_bit_field (word, offset * unit / BITS_PER_UNIT, thissize,
> > + thispos, part);
> > bitsdone += thissize;
>
> "it is just an out-of-bounds access."
Ok, will change, thanks.
Jakub