fold_convert question

Eric Botcazou ebotcazou@libertysurf.fr
Sat Oct 16 20:24:00 GMT 2004


> 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.

-- 
Eric Botcazou



More information about the Gcc mailing list