tree-vrp.c (simplify_conversion_using_ranges): New function.
authorRichard Guenther <rguenther@suse.de>
Thu, 7 Jul 2011 14:20:16 +0000 (14:20 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 7 Jul 2011 14:20:16 +0000 (14:20 +0000)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/scev-cast.c
gcc/testsuite/gcc.dg/tree-ssa/vrp58.c [new file with mode: 0644]
gcc/tree-vrp.c

index 09a817a1e94f6b125fe59e5edd818f3429b1f91c..f3b7c1106c52831e7c4bb54d4d9a583d4541ae62 100644 (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.
index e73b5ea428a17450016255911c2a316f0a1cd33c..910a33368f699a126b16c9938cbd919730034357 100644 (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.
index 8120dad7fe9d5081f54fd2038217ec5508a6de67..ff645fac2ca471f5642d03451faa729490a093e8 100644 (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" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp58.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp58.c
new file mode 100644 (file)
index 0000000..7da3896
--- /dev/null
@@ -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" } } */
index c049c5d426bffcec79bc06c9130cb2d6f8e5f2b7..68998b379919ea2aed8bcdc14050858fda843087 100644 (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;
        }