Following some of my recent middle-end clean-ups, I believe that we're now at the point where incrementally the middle-end can start ignoring the TREE_OVERFLOW bits on constant tree nodes. As a step in this direction, the patch below removes the TREE_CONSTANT_OVERFLOW checks from integer_zerop, integer_onep, and friends in tree.c. This patch bootstraps and regression tests on i686-pc-linux-gnu (including Ada) with no new failures.
The major true user of TREE_CONSTANT_OVERFLOW is the C front-end, which doesn't use any of these functions to determine whether it should issue a diagnostic when an overflowed integer is used in a context requiring a compile-time constant. Over the years, this overflow testing in the middle-end has caused numerous bugs, the most recent being last week's PR26859. Removing this test cleans up the semantics of integer constants a little. In the unlikely event that any problems are discovered, by routines relying on these functions testing checking for overflow, the trivial fix is to rewrite the callers as: if (integer_zerop (t) && ! TREE_CONSTANT_OVERFLOW (t)) ... There is now a stronger requirement on fold-const.c and friends that it now be extra careful preserving TREE_CONSTANT_OVERFLOW for the C front-end. Optimizations such as "0 * x" -> "0" where we test for zero using integer_zerop, have been checked to make sure that we return the original zero, which the overflow bits set as appropriate. Once this patch is approved there's some follow-up clean-up that can be done, removing the duplication in the many "local" functions that test for zero but couldn't previously use integer_zerop due to the historical overflow semantics. Presumably everyone agrees that this evolution is a good thing. The contention is whether everyone agrees that we're ready for such a step. Is such a transition safe for stage 3 mainline, and/or would front-ends prefer some time to double check that this won't cause problems on conformance tests not part of GCC's testsuite. Thoughts? 2006-04-01 Roger Sayle <[EMAIL PROTECTED]> * tree.c (integer_zerop): Ignore TREE_CONSTANT_OVERFLOW. (integer_onep): Likewise. (integer_all_onesp): Likewise. (integer_pow2p): Likewise. (integer_nonzerop): Likewise. (real_zerop): Likewise. (real_onep): Likewise. (real_twop): Likewise. (real_minus_onep): Likewise. (int_size_in_bytes): Likewise. (host_integerp): Likewise. Index: tree.c =================================================================== *** tree.c (revision 112378) --- tree.c (working copy) *************** integer_zerop (tree expr) *** 1209,1215 **** STRIP_NOPS (expr); return ((TREE_CODE (expr) == INTEGER_CST - && ! TREE_CONSTANT_OVERFLOW (expr) && TREE_INT_CST_LOW (expr) == 0 && TREE_INT_CST_HIGH (expr) == 0) || (TREE_CODE (expr) == COMPLEX_CST --- 1209,1214 ---- *************** integer_onep (tree expr) *** 1226,1232 **** STRIP_NOPS (expr); return ((TREE_CODE (expr) == INTEGER_CST - && ! TREE_CONSTANT_OVERFLOW (expr) && TREE_INT_CST_LOW (expr) == 1 && TREE_INT_CST_HIGH (expr) == 0) || (TREE_CODE (expr) == COMPLEX_CST --- 1225,1230 ---- *************** integer_all_onesp (tree expr) *** 1250,1257 **** && integer_zerop (TREE_IMAGPART (expr))) return 1; ! else if (TREE_CODE (expr) != INTEGER_CST ! || TREE_CONSTANT_OVERFLOW (expr)) return 0; uns = TYPE_UNSIGNED (TREE_TYPE (expr)); --- 1248,1254 ---- && integer_zerop (TREE_IMAGPART (expr))) return 1; ! else if (TREE_CODE (expr) != INTEGER_CST) return 0; uns = TYPE_UNSIGNED (TREE_TYPE (expr)); *************** integer_pow2p (tree expr) *** 1303,1309 **** && integer_zerop (TREE_IMAGPART (expr))) return 1; ! if (TREE_CODE (expr) != INTEGER_CST || TREE_CONSTANT_OVERFLOW (expr)) return 0; prec = (POINTER_TYPE_P (TREE_TYPE (expr)) --- 1300,1306 ---- && integer_zerop (TREE_IMAGPART (expr))) return 1; ! if (TREE_CODE (expr) != INTEGER_CST) return 0; prec = (POINTER_TYPE_P (TREE_TYPE (expr)) *************** integer_nonzerop (tree expr) *** 1341,1347 **** STRIP_NOPS (expr); return ((TREE_CODE (expr) == INTEGER_CST - && ! TREE_CONSTANT_OVERFLOW (expr) && (TREE_INT_CST_LOW (expr) != 0 || TREE_INT_CST_HIGH (expr) != 0)) || (TREE_CODE (expr) == COMPLEX_CST --- 1338,1343 ---- *************** real_zerop (tree expr) *** 1434,1440 **** STRIP_NOPS (expr); return ((TREE_CODE (expr) == REAL_CST - && ! TREE_CONSTANT_OVERFLOW (expr) && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0)) || (TREE_CODE (expr) == COMPLEX_CST && real_zerop (TREE_REALPART (expr)) --- 1430,1435 ---- *************** real_onep (tree expr) *** 1449,1455 **** STRIP_NOPS (expr); return ((TREE_CODE (expr) == REAL_CST - && ! TREE_CONSTANT_OVERFLOW (expr) && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1)) || (TREE_CODE (expr) == COMPLEX_CST && real_onep (TREE_REALPART (expr)) --- 1444,1449 ---- *************** real_twop (tree expr) *** 1464,1470 **** STRIP_NOPS (expr); return ((TREE_CODE (expr) == REAL_CST - && ! TREE_CONSTANT_OVERFLOW (expr) && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2)) || (TREE_CODE (expr) == COMPLEX_CST && real_twop (TREE_REALPART (expr)) --- 1458,1463 ---- *************** real_minus_onep (tree expr) *** 1479,1485 **** STRIP_NOPS (expr); return ((TREE_CODE (expr) == REAL_CST - && ! TREE_CONSTANT_OVERFLOW (expr) && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconstm1)) || (TREE_CODE (expr) == COMPLEX_CST && real_minus_onep (TREE_REALPART (expr)) --- 1472,1477 ---- *************** int_size_in_bytes (tree type) *** 1725,1731 **** t = TYPE_SIZE_UNIT (type); if (t == 0 || TREE_CODE (t) != INTEGER_CST - || TREE_OVERFLOW (t) || TREE_INT_CST_HIGH (t) != 0 /* If the result would appear negative, it's too big to represent. */ || (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0) --- 1717,1722 ---- *************** int *** 4404,4410 **** host_integerp (tree t, int pos) { return (TREE_CODE (t) == INTEGER_CST - && ! TREE_OVERFLOW (t) && ((TREE_INT_CST_HIGH (t) == 0 && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) >= 0) || (! pos && TREE_INT_CST_HIGH (t) == -1 --- 4395,4400 ---- Roger --