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

Reply via email to