From 29c5134ac901bba223eb66866cd4be7d30194dc3 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Thu, 7 Jul 2011 14:20:16 +0000 Subject: [PATCH] tree-vrp.c (simplify_conversion_using_ranges): New function. 2011-07-07 Richard Guenther * 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 --- gcc/ChangeLog | 5 +++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/tree-ssa/scev-cast.c | 4 +- gcc/testsuite/gcc.dg/tree-ssa/vrp58.c | 12 ++++++ gcc/tree-vrp.c | 50 ++++++++++++++++++++--- 5 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp58.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 09a817a1e94..f3b7c1106c5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2011-07-07 Richard Guenther + + * tree-vrp.c (simplify_conversion_using_ranges): New function. + (simplify_stmt_using_ranges): Call it. + 2011-07-07 Kai Tietz * tree-ssa-forwprop.c (truth_valued_ssa_name): New function. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e73b5ea428a..910a33368f6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-07-07 Richard Guenther + + * gcc.dg/tree-ssa/vrp58.c: New testcase. + * gcc.dg/tree-ssa/scev-cast.c: Adjust. + 2011-07-07 Kai Tietz * gcc.dg/binop-notxor1.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-cast.c b/gcc/testsuite/gcc.dg/tree-ssa/scev-cast.c index 8120dad7fe9..ff645fac2ca 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/scev-cast.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-cast.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp58.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp58.c new file mode 100644 index 00000000000..7da3896b5b2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp58.c @@ -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" } } */ diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index c049c5d426b..68998b37991 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; } -- 2.30.2