This is the mail archive of the gcc@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]

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


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