aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2013-04-29 06:52:17 -0600
committerJeff Law <law@gcc.gnu.org>2013-04-29 06:52:17 -0600
commitebbd90d832d3f0277f02b30fe03451fe0bbf659d (patch)
tree8eeffe6533adbdfe8771db8a2c7e92e1b6381bcd /gcc/tree-vrp.c
parent8b9b57ebca94b7c16daaed85d3020c06f2412dce (diff)
downloadgcc-ebbd90d832d3f0277f02b30fe03451fe0bbf659d.zip
gcc-ebbd90d832d3f0277f02b30fe03451fe0bbf659d.tar.gz
gcc-ebbd90d832d3f0277f02b30fe03451fe0bbf659d.tar.bz2
tree-vrp.c (range_fits_type_p): Move to earlier point in file.
* tree-vrp.c (range_fits_type_p): Move to earlier point in file. (simplify_cond_using_ranges): Generalize code to simplify COND_EXPRs where one argument is a constant and the other is an SSA_NAME created by an integral type conversion. * gcc.dg/tree-ssa/vrp88.c: New test. From-SVN: r198413
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c124
1 files changed, 61 insertions, 63 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index a740907..6ed353f 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -8509,6 +8509,57 @@ test_for_singularity (enum tree_code cond_code, tree op0,
return NULL;
}
+/* Return whether the value range *VR fits in an integer type specified
+ by PRECISION and UNSIGNED_P. */
+
+static bool
+range_fits_type_p (value_range_t *vr, unsigned precision, bool unsigned_p)
+{
+ tree src_type;
+ unsigned src_precision;
+ double_int tem;
+
+ /* We can only handle integral and pointer types. */
+ src_type = TREE_TYPE (vr->min);
+ if (!INTEGRAL_TYPE_P (src_type)
+ && !POINTER_TYPE_P (src_type))
+ return false;
+
+ /* An extension is fine unless VR is signed and unsigned_p,
+ and so is an identity transform. */
+ src_precision = TYPE_PRECISION (TREE_TYPE (vr->min));
+ if ((src_precision < precision
+ && !(unsigned_p && !TYPE_UNSIGNED (src_type)))
+ || (src_precision == precision
+ && TYPE_UNSIGNED (src_type) == unsigned_p))
+ return true;
+
+ /* Now we can only handle ranges with constant bounds. */
+ if (vr->type != VR_RANGE
+ || TREE_CODE (vr->min) != INTEGER_CST
+ || TREE_CODE (vr->max) != INTEGER_CST)
+ return false;
+
+ /* For sign changes, the MSB of the double_int has to be clear.
+ An unsigned value with its MSB set cannot be represented by
+ a signed double_int, while a negative value cannot be represented
+ by an unsigned double_int. */
+ if (TYPE_UNSIGNED (src_type) != unsigned_p
+ && (TREE_INT_CST_HIGH (vr->min) | TREE_INT_CST_HIGH (vr->max)) < 0)
+ return false;
+
+ /* Then we can perform the conversion on both ends and compare
+ the result for equality. */
+ tem = tree_to_double_int (vr->min).ext (precision, unsigned_p);
+ if (tree_to_double_int (vr->min) != tem)
+ return false;
+ tem = tree_to_double_int (vr->max).ext (precision, unsigned_p);
+ if (tree_to_double_int (vr->max) != tem)
+ return false;
+
+ return true;
+}
+
/* Simplify a conditional using a relational operator to an equality
test if the range information indicates only one value can satisfy
the original conditional. */
@@ -8590,18 +8641,15 @@ simplify_cond_using_ranges (gimple stmt)
}
}
- /* If we have a comparison of a SSA_NAME boolean against
- a constant (which obviously must be [0..1]), see if the
- SSA_NAME was set by a type conversion where the source
- of the conversion is another SSA_NAME with a range [0..1].
+ /* If we have a comparison of an SSA_NAME (OP0) against a constant,
+ see if OP0 was set by a type conversion where the source of
+ the conversion is another SSA_NAME with a range that fits
+ into the range of OP0's type.
- If so, we can replace the SSA_NAME in the comparison with
- the RHS of the conversion. This will often make the type
- conversion dead code which DCE will clean up. */
+ If so, the conversion is redundant as the earlier SSA_NAME can be
+ used for the comparison directly if we just massage the constant in the
+ comparison. */
if (TREE_CODE (op0) == SSA_NAME
- && (TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
- || (INTEGRAL_TYPE_P (TREE_TYPE (op0))
- && TYPE_PRECISION (TREE_TYPE (op0)) == 1))
&& TREE_CODE (op1) == INTEGER_CST)
{
gimple def_stmt = SSA_NAME_DEF_STMT (op0);
@@ -8618,8 +8666,9 @@ simplify_cond_using_ranges (gimple stmt)
value_range_t *vr = get_value_range (innerop);
if (range_int_cst_p (vr)
- && operand_equal_p (vr->min, integer_zero_node, 0)
- && operand_equal_p (vr->max, integer_one_node, 0))
+ && range_fits_type_p (vr,
+ TYPE_PRECISION (TREE_TYPE (op0)),
+ TYPE_UNSIGNED (TREE_TYPE (op0))))
{
tree newconst = fold_convert (TREE_TYPE (innerop), op1);
gimple_cond_set_lhs (stmt, innerop);
@@ -8809,57 +8858,6 @@ simplify_conversion_using_ranges (gimple stmt)
return true;
}
-/* Return whether the value range *VR fits in an integer type specified
- by PRECISION and UNSIGNED_P. */
-
-static bool
-range_fits_type_p (value_range_t *vr, unsigned precision, bool unsigned_p)
-{
- tree src_type;
- unsigned src_precision;
- double_int tem;
-
- /* We can only handle integral and pointer types. */
- src_type = TREE_TYPE (vr->min);
- if (!INTEGRAL_TYPE_P (src_type)
- && !POINTER_TYPE_P (src_type))
- return false;
-
- /* An extension is fine unless VR is signed and unsigned_p,
- and so is an identity transform. */
- src_precision = TYPE_PRECISION (TREE_TYPE (vr->min));
- if ((src_precision < precision
- && !(unsigned_p && !TYPE_UNSIGNED (src_type)))
- || (src_precision == precision
- && TYPE_UNSIGNED (src_type) == unsigned_p))
- return true;
-
- /* Now we can only handle ranges with constant bounds. */
- if (vr->type != VR_RANGE
- || TREE_CODE (vr->min) != INTEGER_CST
- || TREE_CODE (vr->max) != INTEGER_CST)
- return false;
-
- /* For sign changes, the MSB of the double_int has to be clear.
- An unsigned value with its MSB set cannot be represented by
- a signed double_int, while a negative value cannot be represented
- by an unsigned double_int. */
- if (TYPE_UNSIGNED (src_type) != unsigned_p
- && (TREE_INT_CST_HIGH (vr->min) | TREE_INT_CST_HIGH (vr->max)) < 0)
- return false;
-
- /* Then we can perform the conversion on both ends and compare
- the result for equality. */
- tem = tree_to_double_int (vr->min).ext (precision, unsigned_p);
- if (tree_to_double_int (vr->min) != tem)
- return false;
- tem = tree_to_double_int (vr->max).ext (precision, unsigned_p);
- if (tree_to_double_int (vr->max) != tem)
- return false;
-
- return true;
-}
-
/* Simplify a conversion from integral SSA name to float in STMT. */
static bool