aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2011-07-07 14:20:16 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2011-07-07 14:20:16 +0000
commit29c5134ac901bba223eb66866cd4be7d30194dc3 (patch)
treef136ffc88ee435e9cda3b37d111d3f10497c5b11 /gcc/tree-vrp.c
parent0816a42a1fa5f3fa99d5756b35c9e7a94cbdb86e (diff)
downloadgcc-29c5134ac901bba223eb66866cd4be7d30194dc3.zip
gcc-29c5134ac901bba223eb66866cd4be7d30194dc3.tar.gz
gcc-29c5134ac901bba223eb66866cd4be7d30194dc3.tar.bz2
tree-vrp.c (simplify_conversion_using_ranges): New function.
2011-07-07 Richard Guenther <rguenther@suse.de> * tree-vrp.c (simplify_conversion_using_ranges): New function. (simplify_stmt_using_ranges): Call it. * gcc.dg/tree-ssa/vrp58.c: New testcase. * gcc.dg/tree-ssa/scev-cast.c: Adjust. From-SVN: r175975
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c50
1 files changed, 45 insertions, 5 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index c049c5d..68998b37 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -7342,6 +7342,39 @@ simplify_switch_using_ranges (gimple stmt)
return false;
}
+/* Simplify an integral conversion from an SSA name in STMT. */
+
+static bool
+simplify_conversion_using_ranges (gimple stmt)
+{
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ gimple def_stmt = SSA_NAME_DEF_STMT (rhs1);
+ value_range_t *final, *inner;
+
+ /* Obtain final and inner value-ranges for a conversion
+ sequence (final-type)(intermediate-type)inner-type. */
+ final = get_value_range (gimple_assign_lhs (stmt));
+ if (final->type != VR_RANGE)
+ return false;
+ if (!is_gimple_assign (def_stmt)
+ || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
+ return false;
+ rhs1 = gimple_assign_rhs1 (def_stmt);
+ if (TREE_CODE (rhs1) != SSA_NAME)
+ return false;
+ inner = get_value_range (rhs1);
+ if (inner->type != VR_RANGE)
+ return false;
+ /* If the value-range is preserved by the conversion sequence strip
+ the intermediate conversion. */
+ if (!tree_int_cst_equal (final->min, inner->min)
+ || !tree_int_cst_equal (final->max, inner->max))
+ return false;
+ gimple_assign_set_rhs1 (stmt, rhs1);
+ update_stmt (stmt);
+ return true;
+}
+
/* Simplify STMT using ranges if possible. */
static bool
@@ -7351,6 +7384,7 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
if (is_gimple_assign (stmt))
{
enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
+ tree rhs1 = gimple_assign_rhs1 (stmt);
switch (rhs_code)
{
@@ -7364,7 +7398,7 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
or identity if the RHS is zero or one, and the LHS are known
to be boolean values. Transform all TRUTH_*_EXPR into
BIT_*_EXPR if both arguments are known to be boolean values. */
- if (INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt))))
+ if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
return simplify_truth_ops_using_ranges (gsi, stmt);
break;
@@ -7373,15 +7407,15 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
than zero and the second operand is an exact power of two. */
case TRUNC_DIV_EXPR:
case TRUNC_MOD_EXPR:
- if (INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt)))
+ if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
&& integer_pow2p (gimple_assign_rhs2 (stmt)))
return simplify_div_or_mod_using_ranges (stmt);
break;
/* Transform ABS (X) into X or -X as appropriate. */
case ABS_EXPR:
- if (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
- && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt))))
+ if (TREE_CODE (rhs1) == SSA_NAME
+ && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
return simplify_abs_using_ranges (stmt);
break;
@@ -7390,10 +7424,16 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
/* Optimize away BIT_AND_EXPR and BIT_IOR_EXPR
if all the bits being cleared are already cleared or
all the bits being set are already set. */
- if (INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt))))
+ if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
return simplify_bit_ops_using_ranges (gsi, stmt);
break;
+ CASE_CONVERT:
+ if (TREE_CODE (rhs1) == SSA_NAME
+ && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
+ return simplify_conversion_using_ranges (stmt);
+ break;
+
default:
break;
}