tree_ssa_useless_type_conversion is too optimistic

Richard Guenther rguenth@tat.physik.uni-tuebingen.de
Sun May 15 13:00:00 GMT 2005


In fact, tree_ssa_useless_type_conversion_1 contradicts itself if given
the two (C language) pointer types "char *" and "const char *".  Asking
the langhook if they are compatible, it says no.  But then in the
section that reads

  /* Pointers and references are equivalent once we get to GENERIC,
     so strip conversions that just switch between them.  */
  else if (POINTER_TYPE_P (inner_type)
           && POINTER_TYPE_P (outer_type)
           && TYPE_REF_CAN_ALIAS_ALL (inner_type)
              == TYPE_REF_CAN_ALIAS_ALL (outer_type)
           && lang_hooks.types_compatible_p (TREE_TYPE (inner_type),
                                             TREE_TYPE (outer_type)))
    return true;

where, from the comment I read that we want to ignore casts of the form
T* -> T& or T& -> T*.  Of course the logic applies to const T* -> T*,
too and we end up asking the C frontend if "char" and "const char" are
compatible which it happily says yes to (they share the main variant
"char").  So we return true for the compatibiltiy of the pointer types
based on the compatibiltiy of the pointed to types, which looks wrong.

Either we should constrain this test with something like

Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa.c,v
retrieving revision 2.94
diff -c -3 -p -r2.94 tree-ssa.c
*** tree-ssa.c  8 May 2005 15:07:22 -0000       2.94
--- tree-ssa.c  15 May 2005 11:43:35 -0000
*************** tree_ssa_useless_type_conversion_1 (tree
*** 885,890 ****
--- 885,891 ----
       so strip conversions that just switch between them.  */
    else if (POINTER_TYPE_P (inner_type)
             && POINTER_TYPE_P (outer_type)
+          && TREE_CODE (inner_type) != TREE_CODE (outer_type)
           && TYPE_REF_CAN_ALIAS_ALL (inner_type)
              == TYPE_REF_CAN_ALIAS_ALL (outer_type)
             && lang_hooks.types_compatible_p (TREE_TYPE (inner_type),

i.e. only use this form if we really deal with pointer vs. reference
thing, or we should actually test what we want to test -- compatibility
with ignoring the pointer/reference distinction with something like

Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa.c,v
retrieving revision 2.94
diff -c -3 -p -r2.94 tree-ssa.c
*** tree-ssa.c  8 May 2005 15:07:22 -0000       2.94
--- tree-ssa.c  15 May 2005 11:50:36 -0000
*************** tree_ssa_useless_type_conversion_1 (tree
*** 882,895 ****
      return true;

    /* Pointers and references are equivalent once we get to GENERIC,
!      so strip conversions that just switch between them.  */
    else if (POINTER_TYPE_P (inner_type)
             && POINTER_TYPE_P (outer_type)
!          && TYPE_REF_CAN_ALIAS_ALL (inner_type)
!             == TYPE_REF_CAN_ALIAS_ALL (outer_type)
!            && lang_hooks.types_compatible_p (TREE_TYPE (inner_type),
!                                            TREE_TYPE (outer_type)))
!     return true;

    /* If both the inner and outer types are integral types, then the
       conversion is not necessary if they have the same mode and
--- 882,901 ----
      return true;

    /* Pointers and references are equivalent once we get to GENERIC,
!      so strip conversions that just switch between compatible
!      pointer counterparts of them.  */
    else if (POINTER_TYPE_P (inner_type)
             && POINTER_TYPE_P (outer_type)
!          && TREE_CODE (inner_type) != TREE_CODE (outer_type))
!     {
!       if (TREE_CODE (inner_type) == REFERENCE_TYPE)
!       inner_type = build_pointer_type (TREE_TYPE (inner_type));
!       else
!       outer_type = build_pointer_type (TREE_TYPE (outer_type));
!
!       if (lang_hooks.types_compatible_p (inner_type, outer_type))
!         return true;
!     }

    /* If both the inner and outer types are integral types, then the
       conversion is not necessary if they have the same mode and


Note that applying either of these variants, we loose the capability
to do the optimization g++.dg/opt/temp1.C is testing which strongly
hints at that we need to implement this optimization elsewhere instead
of doing possibly bogous transformations in
tree_ssa_useless_type_conversion and/or fold_indirect_ref_1 (note that
the testing was with type-santized fold_indirect_ref_1 for which I
attached the used patch as reference).

We also loose for g++.dg/tree-ssa/ssa-sra-1.C - somewhere we need to
add the ability to fold const-casts from rhs(!) only.

Any objections/preference for applying either of the above patches?

Thanks for any hints out of this type-hell,
Richard.


-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: fix-3
URL: <https://gcc.gnu.org/pipermail/gcc/attachments/20050515/278f4c09/attachment.ksh>


More information about the Gcc mailing list