This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix int_fits_type_p (PR tree-optimization/37525)


On Wed, Sep 17, 2008 at 7:37 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> The recent int_fits_type_p fix for sizetype constants degrades generated
> Fortran code, because size_type_node is a signed type in Fortran.  So
> after force_fit_type_double original say (sizetype) -25 (i.e. weirdly
> encoded -25UL) will become -25L, so it won't even fit into its own type,
> which has type_lower_bound 0 and -25 is smaller than that.
> With this patch we use an unsigned type always, for C/C++ unsigned_type_for
> will just return the passed type immediately, as it has TYPE_UNSIGNED set.
>
> Ok for trunk?

Uhm.  This function does a lot of weird things if at the end it falls back
to fit_double_type.  And the sizetype stuff certainly looks bogus to me.
Something like the following looks more correct?

Index: tree.c
===================================================================
*** tree.c	(revision 140361)
--- tree.c	(working copy)
*************** int_fits_type_p (const_tree c, const_tre
*** 6414,6434 ****
       for "unknown if constant fits", 0 for "constant known *not* to fit" and 1
       for "constant known to fit".  */

!   if (TREE_TYPE (c) == sizetype
        && TYPE_UNSIGNED (TREE_TYPE (c))
!       && TREE_INT_CST_HIGH (c) == -1
!       && !TREE_OVERFLOW (c))
!       /* So c is an unsigned integer which type is sizetype.
           sizetype'd integers are sign extended even though they are
  	 unsigned. If the integer value fits in the lower end word of c,
  	 and if the higher end word has all its bits set to 1, that
  	 means the higher end bits are set to 1 only for sign extension.
  	 So let's convert c into an equivalent zero extended unsigned
  	 integer.  */
!       c = force_fit_type_double (size_type_node,
  				 TREE_INT_CST_LOW (c),
  				 TREE_INT_CST_HIGH (c),
! 				 false, false);
    /* Check if C >= type_low_bound.  */
    if (type_low_bound && TREE_CODE (type_low_bound) == INTEGER_CST)
      {
--- 6414,6435 ----
       for "unknown if constant fits", 0 for "constant known *not* to fit" and 1
       for "constant known to fit".  */

!   if (TYPE_IS_SIZETYPE (TREE_TYPE (c))
        && TYPE_UNSIGNED (TREE_TYPE (c))
!       && !TYPE_IS_SIZETYPE (type))
!       /* So c is an unsigned integer which type is a sizetype and type is not.
           sizetype'd integers are sign extended even though they are
  	 unsigned. If the integer value fits in the lower end word of c,
  	 and if the higher end word has all its bits set to 1, that
  	 means the higher end bits are set to 1 only for sign extension.
  	 So let's convert c into an equivalent zero extended unsigned
  	 integer.  */
!       c = force_fit_type_double (build_nonstandard_integer_type
! 				   (TYPE_PRECISION (TREE_TYPE (c)), true),
  				 TREE_INT_CST_LOW (c),
  				 TREE_INT_CST_HIGH (c),
! 				 false, TREE_OVERFLOW (c));
!
    /* Check if C >= type_low_bound.  */
    if (type_low_bound && TREE_CODE (type_low_bound) == INTEGER_CST)
      {


Does this fix the problem as well?

Richard.

> 2008-09-17  Jakub Jelinek  <jakub@redhat.com>
>
>        PR tree-optimization/37525
>        * tree.c (int_fits_type_p): Fix last change if size_type_node is
>        signed.
>
> --- gcc/tree.c.jj       2008-09-17 17:58:44.000000000 +0200
> +++ gcc/tree.c  2008-09-17 19:07:33.000000000 +0200
> @@ -6425,7 +6425,7 @@ int_fits_type_p (const_tree c, const_tre
>         means the higher end bits are set to 1 only for sign extension.
>         So let's convert c into an equivalent zero extended unsigned
>         integer.  */
> -      c = force_fit_type_double (size_type_node,
> +      c = force_fit_type_double (unsigned_type_for (size_type_node),
>                                 TREE_INT_CST_LOW (c),
>                                 TREE_INT_CST_HIGH (c),
>                                 false, false);
>
>        Jakub
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]