This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Do not use TYPE_CANONICAL in useless_type_conversion
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: Eric Botcazou <ebotcazou at adacore dot com>
- Cc: Jan Hubicka <hubicka at ucw dot cz>, gcc-patches at gcc dot gnu dot org, Richard Biener <rguenther at suse dot de>, Bernd Schmidt <bschmidt at redhat dot com>, law at redhat dot com
- Date: Fri, 9 Oct 2015 19:55:27 +0200
- Subject: Re: Do not use TYPE_CANONICAL in useless_type_conversion
- Authentication-results: sourceware.org; auth=none
- References: <20151002214127 dot GC84720 at kam dot mff dot cuni dot cz> <alpine dot LSU dot 2 dot 11 dot 1510081248520 dot 6516 at zhemvz dot fhfr dot qr> <20151008203036 dot GD90964 at kam dot mff dot cuni dot cz> <1701384 dot N6BZZR1xcT at polaris>
> > 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