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
This commit is contained in:
Richard Guenther 2011-07-07 14:20:16 +00:00 committed by Richard Biener
parent 0816a42a1f
commit 29c5134ac9
5 changed files with 69 additions and 7 deletions

View File

@ -1,3 +1,8 @@
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>
* tree-ssa-forwprop.c (truth_valued_ssa_name): New function.

View File

@ -1,3 +1,8 @@
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>
* gcc.dg/binop-notxor1.c: New test.

View File

@ -12,7 +12,7 @@ void tst(void)
for (i = 0; i < 129; i++) /* This truncation to char has to be preserved. */
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);
for (i = 0; i < 127; i++) /* This one is not necessary, IVOPTS eliminates it. */
blas ((signed char) i);
@ -23,6 +23,6 @@ void tst(void)
}
/* { 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" } } */

View File

@ -0,0 +1,12 @@
/* { 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" } } */

View File

@ -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;
}