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]

[Committed] Reorder tests in int_fits_type_p


The following patch should resolve the new mudflap failures observed
by Andreas Krebbel on s390x.  The middle-end routine int_fits_type_p
has to concern itself both with integer types that have explicit
constant upper and lower bounds, and those that don't (such as those
generated by the Ada front-end).

The current problem is that the complex tests that attempt to infer
reasonable "default" limits based upon signedness and precision are
checked before any explicit bounds.  Clearly, if the front-end has
provided precise bounds those should be examined first, and override
any heuristics based upon the integer type's width.  In Andreas'
failure the fact that the underlying type is 64-bits wide and can
therefore represent any 32-bit value takes precedence over it's explicit
upper bound of ten!  Doh!  Simply permuting the order of tests so that
we don't consider TYPE_PRECISION unless we have to makes more sense.


The following patch has been tested on i686-pc-linux-gnu with a full
"make bootstrap", all default languages and regression tested with a
top-level "make -k check" with no new failures.

Committed to mainline CVS.  Andreas, could you confirm this fixes the
mudflap failures you were seeing on s390x?



2005-01-08  Roger Sayle  <roger@eyesopen.com>

	* tree.c (int_fits_type_p): Always honor integer constant
	TYPE_MIN_VALUE and TYPE_MAX_VALUE if they exist.


Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.460
diff -c -3 -p -r1.460 tree.c
*** tree.c	1 Jan 2005 20:33:28 -0000	1.460
--- tree.c	7 Jan 2005 15:25:38 -0000
*************** int_fits_type_p (tree c, tree type)
*** 4874,4896 ****
  {
    tree type_low_bound = TYPE_MIN_VALUE (type);
    tree type_high_bound = TYPE_MAX_VALUE (type);
!   int ok_for_low_bound, ok_for_high_bound;
!
!   /* Perform some generic filtering first, which may allow making a decision
!      even if the bounds are not constant.  First, negative integers never fit
!      in unsigned types, */
!   if (TYPE_UNSIGNED (type) && tree_int_cst_sgn (c) < 0)
!     return 0;
!
!   /* Second, narrower types always fit in wider ones.  */
!   if (TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (c)))
!     return 1;
!
!   /* Third, unsigned integers with top bit set never fit signed types.  */
!   if (! TYPE_UNSIGNED (type)
!       && TYPE_UNSIGNED (TREE_TYPE (c))
!       && tree_int_cst_msb (c))
!     return 0;

    /* If at least one bound of the type is a constant integer, we can check
       ourselves and maybe make a decision. If no such decision is possible, but
--- 4874,4881 ----
  {
    tree type_low_bound = TYPE_MIN_VALUE (type);
    tree type_high_bound = TYPE_MAX_VALUE (type);
!   bool ok_for_low_bound, ok_for_high_bound;
!   tree tmp;

    /* If at least one bound of the type is a constant integer, we can check
       ourselves and maybe make a decision. If no such decision is possible, but
*************** int_fits_type_p (tree c, tree type)
*** 4902,4944 ****
       for "unknown if constant fits", 0 for "constant known *not* to fit" and 1
       for "constant known to fit".  */

-   ok_for_low_bound = -1;
-   ok_for_high_bound = -1;
-
    /* Check if C >= type_low_bound.  */
    if (type_low_bound && TREE_CODE (type_low_bound) == INTEGER_CST)
      {
!       ok_for_low_bound = ! tree_int_cst_lt (c, type_low_bound);
!       if (! ok_for_low_bound)
  	return 0;
      }

    /* Check if c <= type_high_bound.  */
    if (type_high_bound && TREE_CODE (type_high_bound) == INTEGER_CST)
      {
!       ok_for_high_bound = ! tree_int_cst_lt (type_high_bound, c);
!       if (! ok_for_high_bound)
  	return 0;
      }

    /* If the constant fits both bounds, the result is known.  */
!   if (ok_for_low_bound == 1 && ok_for_high_bound == 1)
      return 1;

    /* If we haven't been able to decide at this point, there nothing more we
       can check ourselves here. Look at the base type if we have one.  */
!   else if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != 0)
      return int_fits_type_p (c, TREE_TYPE (type));

    /* Or to force_fit_type, if nothing else.  */
!   else
!     {
!       tree n = copy_node (c);
!       TREE_TYPE (n) = type;
!       n = force_fit_type (n, -1, false, false);
!       return TREE_INT_CST_HIGH (n) == TREE_INT_CST_HIGH (c)
!              && TREE_INT_CST_LOW (n) == TREE_INT_CST_LOW (c);
!     }
  }

  /* Subprogram of following function.  Called by walk_tree.
--- 4887,4943 ----
       for "unknown if constant fits", 0 for "constant known *not* to fit" and 1
       for "constant known to fit".  */

    /* Check if C >= type_low_bound.  */
    if (type_low_bound && TREE_CODE (type_low_bound) == INTEGER_CST)
      {
!       if (tree_int_cst_lt (c, type_low_bound))
  	return 0;
+       ok_for_low_bound = true;
      }
+   else
+     ok_for_low_bound = false;

    /* Check if c <= type_high_bound.  */
    if (type_high_bound && TREE_CODE (type_high_bound) == INTEGER_CST)
      {
!       if (tree_int_cst_lt (type_high_bound, c))
  	return 0;
+       ok_for_high_bound = true;
      }
+   else
+     ok_for_high_bound = false;

    /* If the constant fits both bounds, the result is known.  */
!   if (ok_for_low_bound && ok_for_high_bound)
      return 1;

+   /* Perform some generic filtering which may allow making a decision
+      even if the bounds are not constant.  First, negative integers
+      never fit in unsigned types, */
+   if (TYPE_UNSIGNED (type) && tree_int_cst_sgn (c) < 0)
+     return 0;
+
+   /* Second, narrower types always fit in wider ones.  */
+   if (TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (c)))
+     return 1;
+
+   /* Third, unsigned integers with top bit set never fit signed types.  */
+   if (! TYPE_UNSIGNED (type)
+       && TYPE_UNSIGNED (TREE_TYPE (c))
+       && tree_int_cst_msb (c))
+     return 0;
+
    /* If we haven't been able to decide at this point, there nothing more we
       can check ourselves here. Look at the base type if we have one.  */
!   if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != 0)
      return int_fits_type_p (c, TREE_TYPE (type));

    /* Or to force_fit_type, if nothing else.  */
!   tmp = copy_node (c);
!   TREE_TYPE (tmp) = type;
!   tmp = force_fit_type (tmp, -1, false, false);
!   return TREE_INT_CST_HIGH (tmp) == TREE_INT_CST_HIGH (c)
!          && TREE_INT_CST_LOW (tmp) == TREE_INT_CST_LOW (c);
  }

  /* Subprogram of following function.  Called by walk_tree.


Roger
--


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