This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
[RFC] Ignore TREE_CONSTANT_OVERFLOW in integer_zerop
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org, <gcc at gcc dot gnu dot org>
- Date: Sat, 1 Apr 2006 20:19:25 -0700 (MST)
- Subject: [RFC] Ignore TREE_CONSTANT_OVERFLOW in integer_zerop
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 <roger@eyesopen.com>
* 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
--