> > The type has BLKmode and size 32. DECL_SIZE of the FIELD_DECL is however 24
> > (see it printed as Ada size).
> 
> Yes, no wonder since it's a bitfield, i.e. DECL_BIT_FIELD is set.
> 
> > The DECL_MODE of the FIELD_DECL is VOIDmode (not printed), while the
> > TYPE_MODE of type contained is BLKmode.
> 
> No, the DECL_MODE of a FIELD_DECL cannot be VOIDmode, it's SImode (printed).

Hmm you are right.  The reason is...
> 
> > Because
> > get_inner_reference compute mode based on DECL_MODE:
> >   if (TREE_CODE (exp) == COMPONENT_REF)
> >     {
> >       tree field = TREE_OPERAND (exp, 1);
> >       size_tree = DECL_SIZE (field);
> >       if (flag_strict_volatile_bitfields > 0
> >           && TREE_THIS_VOLATILE (exp)
> >           && DECL_BIT_FIELD_TYPE (field)
> >           && DECL_MODE (field) != BLKmode)
> >         /* Volatile bitfields should be accessed in the mode of the
> >              field's type, not the mode computed based on the bit
> >              size.  */
> >         mode = TYPE_MODE (DECL_BIT_FIELD_TYPE (field));
> >       else if (!DECL_BIT_FIELD (field))
> >         mode = DECL_MODE (field);

... we initialize mode to be non-VOIDmode only if the field is not bitfield. I 
missed
the flag while looking at the dump.  Indeed the DECL_MODE if FIELD_DECL is 
SImode,
but it is ignored.

> > Index: expr.c
> > ===================================================================
> > --- expr.c  (revision 228604)
> > +++ expr.c  (working copy)
> > @@ -6703,7 +6704,7 @@ store_field (rtx target, HOST_WIDE_INT b
> >       emit_group_store (temp_target, temp, TREE_TYPE (exp), size);
> >       temp = temp_target;
> >     }
> > -      else if (mode == BLKmode)
> > +      else if (GET_MODE (temp) == BLKmode)
> >     {
> >       /* Handle calls that return BLKmode values in registers.  */
> >       if (REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
> 
> This cannot be right, you're short-circuiting the REG_P (temp) test below.

Hmm, it seems that for CALL_EXPR the register is supposed to be non-BLKmode
already.  So I guess only what we need to do is to consider bifields when 
TEMP is blk mode and then we want to convert? what about this?

Honza

Index: expr.c
===================================================================
--- expr.c      (revision 228604)
+++ expr.c      (working copy)
@@ -6703,26 +6703,23 @@ store_field (rtx target, HOST_WIDE_INT b
          emit_group_store (temp_target, temp, TREE_TYPE (exp), size);
          temp = temp_target;
        }
-      else if (mode == BLKmode)
+      /* Handle calls that return BLKmode values in registers.  */
+      else if (mode == BLKmode && (REG_P (temp) && TREE_CODE (exp) == 
CALL_EXPR))
        {
-         /* Handle calls that return BLKmode values in registers.  */
-         if (REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
-           {
-             rtx temp_target = gen_reg_rtx (GET_MODE (temp));
-             copy_blkmode_from_reg (temp_target, temp, TREE_TYPE (exp));
-             temp = temp_target;
-           }
-         else
-           {
-             HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
-             rtx temp_target;
-             mode = smallest_mode_for_size (size * BITS_PER_UNIT, MODE_INT);
-             temp_target = gen_reg_rtx (mode);
-             temp_target
-               = extract_bit_field (temp, size * BITS_PER_UNIT, 0, 1,
-                                    temp_target, mode, mode);
-             temp = temp_target;
-           }
+         rtx temp_target = gen_reg_rtx (GET_MODE (temp));
+         copy_blkmode_from_reg (temp_target, temp, TREE_TYPE (exp));
+         temp = temp_target;
+       }
+      else if (GET_MODE (temp) == BLKmode)
+       {
+         HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
+         rtx temp_target;
+         mode = smallest_mode_for_size (size * BITS_PER_UNIT, MODE_INT);
+         temp_target = gen_reg_rtx (mode);
+         temp_target
+           = extract_bit_field (temp, size * BITS_PER_UNIT, 0, 1,
+                                temp_target, mode, mode);
+         temp = temp_target;
        }
 
       /* Store the value in the bitfield.  */
> 
> -- 
> Eric Botcazou

Reply via email to