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

*From*: Roger Sayle <roger at eyesopen dot com>*To*: gcc-patches at gcc dot gnu dot org*Cc*: Andreas Krebbel <krebbel1 at de dot ibm dot com>*Date*: Sat, 8 Jan 2005 07:27:51 -0700 (MST)*Subject*: [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 --

**Follow-Ups**:**Re: [Committed] Reorder tests in int_fits_type_p***From:*Andreas Krebbel1

**References**:**64 bit mudflap failures***From:*Andreas Krebbel

Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|

Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |