VRP: range info of new variables
authorMarc Glisse <marc.glisse@inria.fr>
Tue, 17 May 2016 17:50:55 +0000 (19:50 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Tue, 17 May 2016 17:50:55 +0000 (17:50 +0000)
2016-05-17  Marc Glisse  <marc.glisse@inria.fr>

gcc/
* tree-vrp.c (simplify_truth_ops_using_ranges): Set range
information for new SSA_NAME.
(simplify_conversion_using_ranges): Get range through get_range_info
instead of get_value_range.

gcc/testsuite/
* gcc.dg/tree-ssa/pr69270.c: Adjust.
* gcc.dg/tree-ssa/vrp99.c: New testcase.

From-SVN: r236336

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr69270.c
gcc/testsuite/gcc.dg/tree-ssa/vrp99.c [new file with mode: 0644]
gcc/tree-vrp.c

index b1d1bc022bc94d738c8e2fd2f38093bbef2d5568..93c1a2d22a1f8a8f4ae27a07b79e2006f154e989 100644 (file)
@@ -1,3 +1,10 @@
+2016-05-17  Marc Glisse  <marc.glisse@inria.fr>
+
+       * tree-vrp.c (simplify_truth_ops_using_ranges): Set range
+       information for new SSA_NAME.
+       (simplify_conversion_using_ranges): Get range through get_range_info
+       instead of get_value_range.
+
 2016-05-17  Jiong Wang  <jiong.wang@arm.com>
 
        * config/aarch64/arm_neon.h (vmvn_s8): Reimplement using C operator.
index b507061213b5a0b28507ddc29d58e08f9fd078b7..ca093a185271de9a9bcde64ccd6522f772f00620 100644 (file)
@@ -1,3 +1,8 @@
+2016-05-17  Marc Glisse  <marc.glisse@inria.fr>
+
+       * gcc.dg/tree-ssa/pr69270.c: Adjust.
+       * gcc.dg/tree-ssa/vrp99.c: New testcase.
+
 2016-05-17  Jiong Wang  <jiong.wang@arm.com>
 
        * gcc.target/aarch64/simd/vmul_elem_1.c: Use intrinsics.
index 28f6d0fac286574a77209b9735f43e7e933c3ae3..0d66cc4383f2d77ba9cf05ff52de8a1bea8d452a 100644 (file)
@@ -7,8 +7,6 @@
 /* { dg-final { scan-tree-dump-times "Replaced .bufferstep_\[0-9\]+. with constant .1." 1 "dom3"} } */
 
 /* And some assignments ought to fold down to constants.  */
-/* { dg-final { scan-tree-dump-times "Folded to: _\[0-9\]+ = -1;" 1 "dom3"} } */
-/* { dg-final { scan-tree-dump-times "Folded to: _\[0-9\]+ = -2;" 1 "dom3"} } */
 /* { dg-final { scan-tree-dump-times "Folded to: _\[0-9\]+ = 1;" 1 "dom3"} } */
 /* { dg-final { scan-tree-dump-times "Folded to: _\[0-9\]+ = 0;" 1 "dom3"} } */
 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp99.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp99.c
new file mode 100644 (file)
index 0000000..baa7a70
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp1" } */
+
+unsigned f(unsigned i){
+  i >>= __SIZEOF_INT__ * __CHAR_BIT__ - 1;
+  return i == 0;
+}
+
+/* { dg-final { scan-tree-dump-not "\\(unsigned int\\)" "vrp1" } } */
index 4cd1ab30b30f58b723b67f61a83b982ba242c451..69e6248a4fcd63ee1a44f934d0859647d7466a83 100644 (file)
@@ -8940,6 +8940,11 @@ simplify_truth_ops_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt)
       gassign *newop
        = gimple_build_assign (tem, BIT_XOR_EXPR, op0, op1);
       gsi_insert_before (gsi, newop, GSI_SAME_STMT);
+      if (INTEGRAL_TYPE_P (TREE_TYPE (tem))
+         && TYPE_PRECISION (TREE_TYPE (tem)) > 1)
+       set_range_info (tem, VR_RANGE,
+                       wi::zero (TYPE_PRECISION (TREE_TYPE (tem))),
+                       wi::one (TYPE_PRECISION (TREE_TYPE (tem))));
       gimple_assign_set_rhs_with_ops (gsi, NOP_EXPR, tem);
     }
   /* Or without.  */
@@ -9648,7 +9653,6 @@ simplify_conversion_using_ranges (gimple *stmt)
 {
   tree innerop, middleop, finaltype;
   gimple *def_stmt;
-  value_range *innervr;
   signop inner_sgn, middle_sgn, final_sgn;
   unsigned inner_prec, middle_prec, final_prec;
   widest_int innermin, innermed, innermax, middlemin, middlemed, middlemax;
@@ -9666,18 +9670,17 @@ simplify_conversion_using_ranges (gimple *stmt)
       || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop))
     return false;
 
-  /* Get the value-range of the inner operand.  */
-  innervr = get_value_range (innerop);
-  if (innervr->type != VR_RANGE
-      || TREE_CODE (innervr->min) != INTEGER_CST
-      || TREE_CODE (innervr->max) != INTEGER_CST)
+  /* Get the value-range of the inner operand.  Use get_range_info in
+     case innerop was created during substitute-and-fold.  */
+  wide_int imin, imax;
+  if (!INTEGRAL_TYPE_P (TREE_TYPE (innerop))
+      || get_range_info (innerop, &imin, &imax) != VR_RANGE)
     return false;
+  innermin = widest_int::from (imin, TYPE_SIGN (TREE_TYPE (innerop)));
+  innermax = widest_int::from (imax, TYPE_SIGN (TREE_TYPE (innerop)));
 
   /* Simulate the conversion chain to check if the result is equal if
      the middle conversion is removed.  */
-  innermin = wi::to_widest (innervr->min);
-  innermax = wi::to_widest (innervr->max);
-
   inner_prec = TYPE_PRECISION (TREE_TYPE (innerop));
   middle_prec = TYPE_PRECISION (TREE_TYPE (middleop));
   final_prec = TYPE_PRECISION (finaltype);