Commit 29c5134a by Richard Guenther Committed by Richard Biener

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
parent 0816a42a
2011-07-07 Richard Guenther <rguenther@suse.de>
* tree-vrp.c (simplify_conversion_using_ranges): New function.
(simplify_stmt_using_ranges): Call it.
2011-07-07 Kai Tietz <ktietz@redhat.com> 2011-07-07 Kai Tietz <ktietz@redhat.com>
* tree-ssa-forwprop.c (truth_valued_ssa_name): New function. * tree-ssa-forwprop.c (truth_valued_ssa_name): New function.
......
2011-07-07 Richard Guenther <rguenther@suse.de>
* gcc.dg/tree-ssa/vrp58.c: New testcase.
* gcc.dg/tree-ssa/scev-cast.c: Adjust.
2011-07-07 Kai Tietz <ktietz@redhat.com> 2011-07-07 Kai Tietz <ktietz@redhat.com>
* gcc.dg/binop-notxor1.c: New test. * gcc.dg/binop-notxor1.c: New test.
......
...@@ -12,7 +12,7 @@ void tst(void) ...@@ -12,7 +12,7 @@ void tst(void)
for (i = 0; i < 129; i++) /* This truncation to char has to be preserved. */ for (i = 0; i < 129; i++) /* This truncation to char has to be preserved. */
blas ((signed char) i); blas ((signed char) i);
for (i = 0; i < 128; i++) /* This one is not necessary, but nothing eliminates it. */ for (i = 0; i < 128; i++) /* This one is not necessary, VRP eliminates it. */
blas ((signed char) i); blas ((signed char) i);
for (i = 0; i < 127; i++) /* This one is not necessary, IVOPTS eliminates it. */ for (i = 0; i < 127; i++) /* This one is not necessary, IVOPTS eliminates it. */
blas ((signed char) i); blas ((signed char) i);
...@@ -23,6 +23,6 @@ void tst(void) ...@@ -23,6 +23,6 @@ void tst(void)
} }
/* { dg-final { scan-tree-dump-times "& 255" 1 "optimized" } } */ /* { dg-final { scan-tree-dump-times "& 255" 1 "optimized" } } */
/* { dg-final { scan-tree-dump-times "= \\(signed char\\)" 2 "optimized" } } */ /* { dg-final { scan-tree-dump-times "= \\(signed char\\)" 1 "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-vrp1-details" } */
long long
foo (long long a, signed char b, signed char c)
{
int bc = b * c;
return a + (short)bc;
}
/* { dg-final { scan-tree-dump "Folded into" "vrp1" } } */
/* { dg-final { cleanup-tree-dump "vrp1" } } */
...@@ -7342,6 +7342,39 @@ simplify_switch_using_ranges (gimple stmt) ...@@ -7342,6 +7342,39 @@ simplify_switch_using_ranges (gimple stmt)
return false; 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. */ /* Simplify STMT using ranges if possible. */
static bool static bool
...@@ -7351,6 +7384,7 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi) ...@@ -7351,6 +7384,7 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
if (is_gimple_assign (stmt)) if (is_gimple_assign (stmt))
{ {
enum tree_code rhs_code = gimple_assign_rhs_code (stmt); enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
tree rhs1 = gimple_assign_rhs1 (stmt);
switch (rhs_code) switch (rhs_code)
{ {
...@@ -7364,7 +7398,7 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi) ...@@ -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 or identity if the RHS is zero or one, and the LHS are known
to be boolean values. Transform all TRUTH_*_EXPR into to be boolean values. Transform all TRUTH_*_EXPR into
BIT_*_EXPR if both arguments are known to be boolean values. */ 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); return simplify_truth_ops_using_ranges (gsi, stmt);
break; break;
...@@ -7373,15 +7407,15 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi) ...@@ -7373,15 +7407,15 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
than zero and the second operand is an exact power of two. */ than zero and the second operand is an exact power of two. */
case TRUNC_DIV_EXPR: case TRUNC_DIV_EXPR:
case TRUNC_MOD_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))) && integer_pow2p (gimple_assign_rhs2 (stmt)))
return simplify_div_or_mod_using_ranges (stmt); return simplify_div_or_mod_using_ranges (stmt);
break; break;
/* Transform ABS (X) into X or -X as appropriate. */ /* Transform ABS (X) into X or -X as appropriate. */
case ABS_EXPR: case ABS_EXPR:
if (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME if (TREE_CODE (rhs1) == SSA_NAME
&& INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt)))) && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
return simplify_abs_using_ranges (stmt); return simplify_abs_using_ranges (stmt);
break; break;
...@@ -7390,10 +7424,16 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi) ...@@ -7390,10 +7424,16 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
/* Optimize away BIT_AND_EXPR and BIT_IOR_EXPR /* Optimize away BIT_AND_EXPR and BIT_IOR_EXPR
if all the bits being cleared are already cleared or if all the bits being cleared are already cleared or
all the bits being set are already set. */ 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); return simplify_bit_ops_using_ranges (gsi, stmt);
break; break;
CASE_CONVERT:
if (TREE_CODE (rhs1) == SSA_NAME
&& INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
return simplify_conversion_using_ranges (stmt);
break;
default: default:
break; break;
} }
......
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