fold_convert question

Jeffrey A Law law@redhat.com
Mon Oct 18 20:57:00 GMT 2004


On Sat, 2004-10-16 at 06:33, Eric Botcazou wrote:
> > If there's anything I can do to help you investigate/fix c61008a
> > that avoids further degenerating the middle-end's type system, I'd
> > be happy to help.  Ultimately, this might be a loosing crusade,
> > but I couldn't forgive myself if I didn't try.  Worst case scenario
> > of tweaking useless_type_conversions is that we miss some optimizations
> > (until we get a tree-ssa combiner), but of perverting fold_convert
> > is that we regress many difficult to diagnose code generation bugs.
> 
> I ran into another problem with tree_ssa_useless_type_conversion, which 
> prevents the Ada RTS from building on SPARC and PPC (PR middle-end/17793).
> 
> The front-end generates
> 
>   ADDR_EXPR <pointer_type <record_type>>
>     VIEW_CONVERT_EXPR <record_type>
>       NOP_EXPR <integer_type1>
>         ARRAY_REF <integer_type2>
> 
> with integer_type1 and integer_type2 not compatible.
> 
> The gimplifier (gimplify_addr_expr) turns this into
> 
>   ADDR_EXPR <pointer_type <integer_type1>>
>     NOP_EXPR <integer_type1>
>       ARRAY_REF <integer_type2>
> 
> and then STRIP_USELESS_TYPE_CONVERSION removes the NOP because of
> 
>   /* If both the inner and outer types are integral types, then the
>      conversion is not necessary if they have the same mode and
>      signedness and precision, and both or neither are boolean.  Some
>      code assumes an invariant that boolean types stay boolean and do
>      not become 1-bit bit-field types.  Note that types with precision
>      not using all bits of the mode (such as bit-field types in C)
>      mean that testing of precision is necessary.  */
>   else if (INTEGRAL_TYPE_P (inner_type)
>            && INTEGRAL_TYPE_P (outer_type)
> 	   && TYPE_MODE (inner_type) == TYPE_MODE (outer_type)
> 	   && TYPE_UNSIGNED (inner_type) == TYPE_UNSIGNED (outer_type)
> 	   && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type))
>     {
>       bool first_boolean = (TREE_CODE (inner_type) == BOOLEAN_TYPE);
>       bool second_boolean = (TREE_CODE (outer_type) == BOOLEAN_TYPE);
>       if (first_boolean == second_boolean)
> 	return true;
>     }
> 
> so we end up with
> 
>   ADDR_EXPR <pointer_type <integer_type1>>
>     ARRAY_REF <integer_type2>
> 
> which causes the gimplifier to later ICE in check_pointer_types_r because 
> cpt_same_type returns false for (integer_type1, integer_type2).
> 
> 
> On the one hand, it seems to me that this is a consistency problem within the 
> gimplifier and that cpt_same_type should accept the pairs of types deemed 
> equivalent by tree_ssa_useless_type_conversion.  On the other hand, 
> check_pointer_types_r seems to be very strict on purpose so perhaps the NOP 
> should not have been stripped in the first place.
> 
> What do (both of) you think about that?  Thanks in advance.
It seems to me we'd be best off turning:

  ADDR_EXPR <pointer_type <record_type>>
    VIEW_CONVERT_EXPR <record_type>
      NOP_EXPR <integer_type1>
        ARRAY_REF <integer_type2>

Into

NOP_EXPR <integer_type1>
  ADDR_EXPR <pointer_type <integer_type2>>
    ARRAY_REF <integer_type2>

I don't know how difficult that would be though.

Jeff



More information about the Gcc mailing list