Commit 55c8849f by Eric Botcazou Committed by Eric Botcazou

tree-vrp.c (compare_values_warnv): Simplify handling of symbolic ranges by…

tree-vrp.c (compare_values_warnv): Simplify handling of symbolic ranges by calling get_single_symbol and tidy up.

	* tree-vrp.c (compare_values_warnv): Simplify handling of symbolic
	ranges by calling get_single_symbol and tidy up.  Look more closely
	into NAME + CST1 vs CST2 comparisons if type overflow is undefined.
ada/
	* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Signed_Integer_Subtype>:
	Make same-sized subtypes of signed base types signed.
	* gcc-interface/utils.c (make_type_from_size): Adjust to above change.
	(unchecked_convert): Likewise.

From-SVN: r236548
parent aa6d7407
2016-05-20 Eric Botcazou <ebotcazou@adacore.com>
* tree-vrp.c (compare_values_warnv): Simplify handling of symbolic
ranges by calling get_single_symbol and tidy up. Look more closely
into NAME + CST1 vs CST2 comparisons if type overflow is undefined.
2016-05-20 Jeff Law <law@redhat.com> 2016-05-20 Jeff Law <law@redhat.com>
* bitmap.c (bitmap_find_bit): Remove useless test. * bitmap.c (bitmap_find_bit): Remove useless test.
......
2016-05-20 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Signed_Integer_Subtype>:
Make same-sized subtypes of signed base types signed.
* gcc-interface/utils.c (make_type_from_size): Adjust to above change.
(unchecked_convert): Likewise.
2016-05-16 Eric Botcazou <ebotcazou@adacore.com> 2016-05-16 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Variable>: Do not build * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Variable>: Do not build
......
...@@ -1814,7 +1814,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) ...@@ -1814,7 +1814,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
/* First subtypes of Character are treated as Character; otherwise /* First subtypes of Character are treated as Character; otherwise
this should be an unsigned type if the base type is unsigned or this should be an unsigned type if the base type is unsigned or
if the lower bound is constant and non-negative or if the type if the lower bound is constant and non-negative or if the type
is biased. */ is biased. However, even if the lower bound is constant and
non-negative, we use a signed type for a subtype with the same
size as its signed base type, because this eliminates useless
conversions to it and gives more leeway to the optimizer; but
this means that we will need to explicitly test for this case
when we change the representation based on the RM size. */
if (kind == E_Enumeration_Subtype if (kind == E_Enumeration_Subtype
&& No (First_Literal (Etype (gnat_entity))) && No (First_Literal (Etype (gnat_entity)))
&& Esize (gnat_entity) == RM_Size (gnat_entity) && Esize (gnat_entity) == RM_Size (gnat_entity)
...@@ -1822,7 +1827,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) ...@@ -1822,7 +1827,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
&& flag_signed_char) && flag_signed_char)
gnu_type = make_signed_type (CHAR_TYPE_SIZE); gnu_type = make_signed_type (CHAR_TYPE_SIZE);
else if (Is_Unsigned_Type (Etype (gnat_entity)) else if (Is_Unsigned_Type (Etype (gnat_entity))
|| Is_Unsigned_Type (gnat_entity) || (Esize (Etype (gnat_entity)) != Esize (gnat_entity)
&& Is_Unsigned_Type (gnat_entity))
|| Has_Biased_Representation (gnat_entity)) || Has_Biased_Representation (gnat_entity))
gnu_type = make_unsigned_type (esize); gnu_type = make_unsigned_type (esize);
else else
......
...@@ -1116,7 +1116,14 @@ make_type_from_size (tree type, tree size_tree, bool for_biased) ...@@ -1116,7 +1116,14 @@ make_type_from_size (tree type, tree size_tree, bool for_biased)
break; break;
biased_p |= for_biased; biased_p |= for_biased;
if (TYPE_UNSIGNED (type) || biased_p)
/* The type should be an unsigned type if the original type is unsigned
or if the lower bound is constant and non-negative or if the type is
biased, see E_Signed_Integer_Subtype case of gnat_to_gnu_entity. */
if (TYPE_UNSIGNED (type)
|| (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST
&& tree_int_cst_sgn (TYPE_MIN_VALUE (type)) >= 0)
|| biased_p)
new_type = make_unsigned_type (size); new_type = make_unsigned_type (size);
else else
new_type = make_signed_type (size); new_type = make_signed_type (size);
...@@ -5111,7 +5118,9 @@ unchecked_convert (tree type, tree expr, bool notrunc_p) ...@@ -5111,7 +5118,9 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
/* If the result is an integral type whose precision is not equal to its /* If the result is an integral type whose precision is not equal to its
size, sign- or zero-extend the result. We need not do this if the input size, sign- or zero-extend the result. We need not do this if the input
is an integral type of the same precision and signedness or if the output is an integral type of the same precision and signedness or if the output
is a biased type or if both the input and output are unsigned. */ is a biased type or if both the input and output are unsigned, or if the
lower bound is constant and non-negative, see E_Signed_Integer_Subtype
case of gnat_to_gnu_entity. */
if (!notrunc_p if (!notrunc_p
&& INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (type)
&& TYPE_RM_SIZE (type) && TYPE_RM_SIZE (type)
...@@ -5123,7 +5132,10 @@ unchecked_convert (tree type, tree expr, bool notrunc_p) ...@@ -5123,7 +5132,10 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
? TYPE_RM_SIZE (etype) ? TYPE_RM_SIZE (etype)
: TYPE_SIZE (etype)) == 0) : TYPE_SIZE (etype)) == 0)
&& !(code == INTEGER_TYPE && TYPE_BIASED_REPRESENTATION_P (type)) && !(code == INTEGER_TYPE && TYPE_BIASED_REPRESENTATION_P (type))
&& !(TYPE_UNSIGNED (type) && TYPE_UNSIGNED (etype))) && !((TYPE_UNSIGNED (type)
|| (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST
&& tree_int_cst_sgn (TYPE_MIN_VALUE (type)) >= 0))
&& TYPE_UNSIGNED (etype)))
{ {
tree base_type tree base_type
= gnat_type_for_size (TREE_INT_CST_LOW (TYPE_SIZE (type)), = gnat_type_for_size (TREE_INT_CST_LOW (TYPE_SIZE (type)),
......
2016-05-20 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/opt53.adb: New test.
* gnat.dg/opt54.adb: Likewise.
2016-05-20 Martin Jambor <mjambor@suse.cz> 2016-05-20 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/70884 PR tree-optimization/70884
......
-- { dg-do compile }
-- { dg-options "-O2 -fdump-tree-optimized" }
function Opt53 (Val, Max : Positive) return Positive is
begin
if Val >= Max then
return Max;
end if;
return Val + 1;
end;
-- { dg-final { scan-tree-dump-not "gnat_rcheck" "optimized" } }
-- { dg-do compile }
-- { dg-options "-O2 -fdump-tree-optimized" }
function Opt54 (Val, Max : Integer) return Integer is
begin
if Val >= Max then
return Max;
end if;
return Val + 1;
end;
-- { dg-final { scan-tree-dump-not "gnat_rcheck" "optimized" } }
...@@ -1187,129 +1187,77 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p) ...@@ -1187,129 +1187,77 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p)
val2 = fold_convert (TREE_TYPE (val1), val2); val2 = fold_convert (TREE_TYPE (val1), val2);
STRIP_USELESS_TYPE_CONVERSION (val2); STRIP_USELESS_TYPE_CONVERSION (val2);
if ((TREE_CODE (val1) == SSA_NAME const bool overflow_undefined
|| (TREE_CODE (val1) == NEGATE_EXPR = INTEGRAL_TYPE_P (TREE_TYPE (val1))
&& TREE_CODE (TREE_OPERAND (val1, 0)) == SSA_NAME) && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (val1));
|| TREE_CODE (val1) == PLUS_EXPR tree inv1, inv2;
|| TREE_CODE (val1) == MINUS_EXPR) bool neg1, neg2;
&& (TREE_CODE (val2) == SSA_NAME tree sym1 = get_single_symbol (val1, &neg1, &inv1);
|| (TREE_CODE (val2) == NEGATE_EXPR tree sym2 = get_single_symbol (val2, &neg2, &inv2);
&& TREE_CODE (TREE_OPERAND (val2, 0)) == SSA_NAME)
|| TREE_CODE (val2) == PLUS_EXPR /* If VAL1 and VAL2 are of the form '[-]NAME [+ CST]', return -1 or +1
|| TREE_CODE (val2) == MINUS_EXPR)) accordingly. If VAL1 and VAL2 don't use the same name, return -2. */
{ if (sym1 && sym2)
tree n1, c1, n2, c2; {
enum tree_code code1, code2; /* Both values must use the same name with the same sign. */
if (sym1 != sym2 || neg1 != neg2)
/* If VAL1 and VAL2 are of the form '[-]NAME [+-] CST' or 'NAME',
return -1 or +1 accordingly. If VAL1 and VAL2 don't use the
same name, return -2. */
if (TREE_CODE (val1) == SSA_NAME || TREE_CODE (val1) == NEGATE_EXPR)
{
code1 = SSA_NAME;
n1 = val1;
c1 = NULL_TREE;
}
else
{
code1 = TREE_CODE (val1);
n1 = TREE_OPERAND (val1, 0);
c1 = TREE_OPERAND (val1, 1);
if (tree_int_cst_sgn (c1) == -1)
{
if (is_negative_overflow_infinity (c1))
return -2;
c1 = fold_unary_to_constant (NEGATE_EXPR, TREE_TYPE (c1), c1);
if (!c1)
return -2;
code1 = code1 == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR;
}
}
if (TREE_CODE (val2) == SSA_NAME || TREE_CODE (val2) == NEGATE_EXPR)
{
code2 = SSA_NAME;
n2 = val2;
c2 = NULL_TREE;
}
else
{
code2 = TREE_CODE (val2);
n2 = TREE_OPERAND (val2, 0);
c2 = TREE_OPERAND (val2, 1);
if (tree_int_cst_sgn (c2) == -1)
{
if (is_negative_overflow_infinity (c2))
return -2; return -2;
c2 = fold_unary_to_constant (NEGATE_EXPR, TREE_TYPE (c2), c2);
if (!c2)
return -2;
code2 = code2 == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR;
}
}
/* Both values must use the same name. */ /* [-]NAME + CST == [-]NAME + CST. */
if (TREE_CODE (n1) == NEGATE_EXPR && TREE_CODE (n2) == NEGATE_EXPR) if (inv1 == inv2)
{
n1 = TREE_OPERAND (n1, 0);
n2 = TREE_OPERAND (n2, 0);
}
if (n1 != n2)
return -2;
if (code1 == SSA_NAME && code2 == SSA_NAME)
/* NAME == NAME */
return 0; return 0;
/* If overflow is defined we cannot simplify more. */ /* If overflow is defined we cannot simplify more. */
if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (val1))) if (!overflow_undefined)
return -2; return -2;
if (strict_overflow_p != NULL if (strict_overflow_p != NULL
&& (code1 == SSA_NAME || !TREE_NO_WARNING (val1)) && (!inv1 || !TREE_NO_WARNING (val1))
&& (code2 == SSA_NAME || !TREE_NO_WARNING (val2))) && (!inv2 || !TREE_NO_WARNING (val2)))
*strict_overflow_p = true; *strict_overflow_p = true;
if (code1 == SSA_NAME) if (!inv1)
{ inv1 = build_int_cst (TREE_TYPE (val1), 0);
if (code2 == PLUS_EXPR) if (!inv2)
/* NAME < NAME + CST */ inv2 = build_int_cst (TREE_TYPE (val2), 0);
return -1;
else if (code2 == MINUS_EXPR) return compare_values_warnv (inv1, inv2, strict_overflow_p);
/* NAME > NAME - CST */
return 1;
} }
else if (code1 == PLUS_EXPR)
const bool cst1 = is_gimple_min_invariant (val1);
const bool cst2 = is_gimple_min_invariant (val2);
/* If one is of the form '[-]NAME + CST' and the other is constant, then
it might be possible to say something depending on the constants. */
if ((sym1 && inv1 && cst2) || (sym2 && inv2 && cst1))
{ {
if (code2 == SSA_NAME) if (!overflow_undefined)
/* NAME + CST > NAME */ return -2;
return 1;
else if (code2 == PLUS_EXPR) if (strict_overflow_p != NULL
/* NAME + CST1 > NAME + CST2, if CST1 > CST2 */ && (!sym1 || !TREE_NO_WARNING (val1))
return compare_values_warnv (c1, c2, strict_overflow_p); && (!sym2 || !TREE_NO_WARNING (val2)))
else if (code2 == MINUS_EXPR) *strict_overflow_p = true;
/* NAME + CST1 > NAME - CST2 */
return 1; const signop sgn = TYPE_SIGN (TREE_TYPE (val1));
} tree cst = cst1 ? val1 : val2;
else if (code1 == MINUS_EXPR) tree inv = cst1 ? inv2 : inv1;
/* Compute the difference between the constants. If it overflows or
underflows, this means that we can trivially compare the NAME with
it and, consequently, the two values with each other. */
wide_int diff = wi::sub (cst, inv);
if (wi::cmp (0, inv, sgn) != wi::cmp (diff, cst, sgn))
{ {
if (code2 == SSA_NAME) const int res = wi::cmp (cst, inv, sgn);
/* NAME - CST < NAME */ return cst1 ? res : -res;
return -1;
else if (code2 == PLUS_EXPR)
/* NAME - CST1 < NAME + CST2 */
return -1;
else if (code2 == MINUS_EXPR)
/* NAME - CST1 > NAME - CST2, if CST1 < CST2. Notice that
C1 and C2 are swapped in the call to compare_values. */
return compare_values_warnv (c2, c1, strict_overflow_p);
} }
gcc_unreachable (); return -2;
} }
/* We cannot compare non-constants. */ /* We cannot say anything more for non-constants. */
if (!is_gimple_min_invariant (val1) || !is_gimple_min_invariant (val2)) if (!cst1 || !cst2)
return -2; return -2;
if (!POINTER_TYPE_P (TREE_TYPE (val1))) if (!POINTER_TYPE_P (TREE_TYPE (val1)))
......
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