Commit 5b429886 by Jakub Jelinek Committed by Jakub Jelinek

re PR tree-optimization/37525 (IVOPTS difference causing 20% degradation in 173.applu benchmark)

	PR tree-optimization/37525
	* tree.c (int_fits_type_p): Rewrite using double_int.  Zero extend
	sizetype unsigned constants, both in the case of C and bounds.

From-SVN: r141164
parent c39a4ad7
2008-10-16 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/37525
* tree.c (int_fits_type_p): Rewrite using double_int. Zero extend
sizetype unsigned constants, both in the case of C and bounds.
2008-10-15 Jan Hubicka <jh@suse.cz>
* ira-emit.c (change_regs): Return false when replacing reg by
......
......@@ -6406,11 +6406,28 @@ get_narrower (tree op, int *unsignedp_ptr)
int
int_fits_type_p (const_tree c, const_tree type)
{
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;
unsigned HOST_WIDE_INT low;
HOST_WIDE_INT high;
tree type_low_bound, type_high_bound;
bool ok_for_low_bound, ok_for_high_bound, unsc;
double_int dc, dd;
dc = tree_to_double_int (c);
unsc = TYPE_UNSIGNED (TREE_TYPE (c));
if (TREE_CODE (TREE_TYPE (c)) == INTEGER_TYPE
&& TYPE_IS_SIZETYPE (TREE_TYPE (c))
&& unsc)
/* So c is an unsigned integer whose type is sizetype and type is not.
sizetype'd integers are sign extended even though they are
unsigned. If the integer value fits in the lower end word of c,
and if the higher end word has all its bits set to 1, that
means the higher end bits are set to 1 only for sign extension.
So let's convert c into an equivalent zero extended unsigned
integer. */
dc = double_int_zext (dc, TYPE_PRECISION (TREE_TYPE (c)));
retry:
type_low_bound = TYPE_MIN_VALUE (type);
type_high_bound = TYPE_MAX_VALUE (type);
/* 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
......@@ -6422,25 +6439,25 @@ int_fits_type_p (const_tree c, const_tree type)
for "unknown if constant fits", 0 for "constant known *not* to fit" and 1
for "constant known to fit". */
if (TREE_TYPE (c) == sizetype
&& TYPE_UNSIGNED (TREE_TYPE (c))
&& TREE_INT_CST_HIGH (c) == -1
&& !TREE_OVERFLOW (c))
/* So c is an unsigned integer which type is sizetype.
sizetype'd integers are sign extended even though they are
unsigned. If the integer value fits in the lower end word of c,
and if the higher end word has all its bits set to 1, that
means the higher end bits are set to 1 only for sign extension.
So let's convert c into an equivalent zero extended unsigned
integer. */
c = force_fit_type_double (size_type_node,
TREE_INT_CST_LOW (c),
TREE_INT_CST_HIGH (c),
false, false);
/* Check if C >= type_low_bound. */
/* 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))
dd = tree_to_double_int (type_low_bound);
if (TREE_CODE (type) == INTEGER_TYPE
&& TYPE_IS_SIZETYPE (type)
&& TYPE_UNSIGNED (type))
dd = double_int_zext (dd, TYPE_PRECISION (type));
if (unsc != TYPE_UNSIGNED (TREE_TYPE (type_low_bound)))
{
int c_neg = (!unsc && double_int_negative_p (dc));
int t_neg = (unsc && double_int_negative_p (dd));
if (c_neg && !t_neg)
return 0;
if ((c_neg || !t_neg) && double_int_ucmp (dc, dd) < 0)
return 0;
}
else if (double_int_cmp (dc, dd, unsc) < 0)
return 0;
ok_for_low_bound = true;
}
......@@ -6450,7 +6467,22 @@ int_fits_type_p (const_tree c, const_tree type)
/* 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))
dd = tree_to_double_int (type_high_bound);
if (TREE_CODE (type) == INTEGER_TYPE
&& TYPE_IS_SIZETYPE (type)
&& TYPE_UNSIGNED (type))
dd = double_int_zext (dd, TYPE_PRECISION (type));
if (unsc != TYPE_UNSIGNED (TREE_TYPE (type_high_bound)))
{
int c_neg = (!unsc && double_int_negative_p (dc));
int t_neg = (unsc && double_int_negative_p (dd));
if (t_neg && !c_neg)
return 0;
if ((t_neg || !c_neg) && double_int_ucmp (dc, dd) > 0)
return 0;
}
else if (double_int_cmp (dc, dd, unsc) > 0)
return 0;
ok_for_high_bound = true;
}
......@@ -6464,7 +6496,7 @@ int_fits_type_p (const_tree c, const_tree type)
/* 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)
if (TYPE_UNSIGNED (type) && !unsc && double_int_negative_p (dc))
return 0;
/* Second, narrower types always fit in wider ones. */
......@@ -6472,10 +6504,18 @@ int_fits_type_p (const_tree c, const_tree type)
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 (! TYPE_UNSIGNED (type) && unsc)
{
int prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (c))) - 1;
if (prec < HOST_BITS_PER_WIDE_INT)
{
if (((((unsigned HOST_WIDE_INT) 1) << prec) & dc.low) != 0)
return 0;
}
else if (((((unsigned HOST_WIDE_INT) 1)
<< (prec - HOST_BITS_PER_WIDE_INT)) & dc.high) != 0)
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 and it
......@@ -6483,12 +6523,13 @@ int_fits_type_p (const_tree c, const_tree type)
if (TREE_CODE (type) == INTEGER_TYPE
&& TREE_TYPE (type) != 0
&& TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (type)))
return int_fits_type_p (c, TREE_TYPE (type));
{
type = TREE_TYPE (type);
goto retry;
}
/* Or to fit_double_type, if nothing else. */
low = TREE_INT_CST_LOW (c);
high = TREE_INT_CST_HIGH (c);
return !fit_double_type (low, high, &low, &high, type);
return !fit_double_type (dc.low, dc.high, &dc.low, &dc.high, type);
}
/* Stores bounds of an integer TYPE in MIN and MAX. If TYPE has non-constant
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment