diff mbox

[RFC] Use ccp mask and val to refine value_range

Message ID 9f3e00ae-a0c7-0047-c2e7-6578d9300171@linaro.org
State New
Headers show

Commit Message

Kugan Vivekanandarajah Aug. 8, 2016, 1:41 a.m. UTC
Hi All,

I was experimenting with using ccp mask and value to refine value_ranges 
for SSA_NAME. Attached patch does this. This might be particularly 
useful for early_vrp. Bootstrap on x86_64-linux-gnu is OK. However, 
there are some test-cases (as shown below) are failing.


Is this worth investigating? Any thoughts?

# Comparing directories
## Dir1=build-base/: 11 sum files
## Dir2=build: 11 sum files

# Comparing 11 common sum files
## /bin/sh ./gcc/contrib/compare_tests  /tmp/gxx-sum1.26167 
/tmp/gxx-sum2.26167
Tests that now fail, but worked before:

gcc.c-torture/execute/pr57124.c   -O2  execution test
gcc.c-torture/execute/pr57124.c   -O2 -flto -fno-use-linker-plugin 
-flto-partition=none  execution test
gcc.c-torture/execute/pr57124.c   -O3 -g  execution test
gcc.c-torture/execute/pr57124.c   -Os  execution test
gcc.dg/Wstrict-overflow-12.c correct warning (test for warnings, line 13)
gcc.dg/Wstrict-overflow-13.c correct warning (test for warnings, line 14)
gcc.dg/Wstrict-overflow-21.c correct warning (test for warnings, line 8)
gcc.dg/no-strict-overflow-6.c scan-tree-dump optimized "return 0"
gcc.dg/tree-ssa/pr61743-1.c scan-tree-dump-times cunroll "loop with 4 
iterations completely unrolled" 2
gcc.dg/tree-ssa/pr61743-1.c scan-tree-dump-times cunroll "loop with 8 
iterations completely unrolled" 2
gcc.dg/tree-ssa/ssa-dom-thread-7.c scan-tree-dump thread3 "Jumps 
threaded: 3"

## Differences found:
# 1 differences in 11 common sum files found


Thanks,
Kugan


gcc/ChangeLog:

2016-08-08  Kugan Vivekanandarajah  <kugan.vivekanandarajah@linaro.org>

	* tree-ssanames.c (refine_range_info): New.
	* tree-ssa-ccp.c (ccp_finalize): Call refine_range_info.
	* tree-ssanames.c (refine_range_info): Declare.
diff mbox

Patch

diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index ae120a8..e7326c7 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -940,8 +940,14 @@  ccp_finalize (bool nonzero_p)
 	  unsigned int precision = TYPE_PRECISION (TREE_TYPE (val->value));
 	  wide_int nonzero_bits = wide_int::from (val->mask, precision,
 						  UNSIGNED) | val->value;
+	  wide_int mask = wide_int::from (val->mask, TYPE_PRECISION (TREE_TYPE (name)),
+					  TYPE_SIGN (TREE_TYPE (name)));
+	  wide_int ones = wi::bit_and (val->value, wi::bit_not (mask));
+	  wide_int zeros = wi::bit_not (wi::bit_and (wi::bit_not (val->value),
+						     wi::bit_not (mask)));
 	  nonzero_bits &= get_nonzero_bits (name);
 	  set_nonzero_bits (name, nonzero_bits);
+	  refine_range_info (name, zeros, ones);
 	}
     }
 
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 91a8f97..a69d8e9 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -388,6 +388,36 @@  set_nonzero_bits (tree name, const wide_int_ref &mask)
   ri->set_nonzero_bits (mask);
 }
 
+/* Refine value range of NAME based on allways ZEROS and always ONES bits.  */
+void
+refine_range_info (tree name, const wide_int_ref &zeros,
+		   const wide_int_ref &ones)
+{
+  tree type = TREE_TYPE (name);
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  if (SSA_NAME_RANGE_INFO (name) == NULL)
+    set_range_info (name, VR_RANGE,
+		    TYPE_MIN_VALUE (type),
+		    TYPE_MAX_VALUE (type));
+
+  if (SSA_NAME_RANGE_TYPE (name) != VR_RANGE)
+    return;
+
+  wide_int min = wi::min_value (type);
+  wide_int max = wi::max_value (type);
+
+  max &= zeros;
+  max |= ones;
+  min &= zeros;
+  min |= ones;
+
+  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
+  if (wi::cmp (ri->get_min(), min, TYPE_SIGN (TREE_TYPE (name))) == -1)
+    ri->set_min (min);
+  if (wi::cmp (max, ri->get_max(), TYPE_SIGN (TREE_TYPE (name))) == -1)
+    ri->set_max (max);
+}
+
 /* Return a widest_int with potentially non-zero bits in SSA_NAME
    NAME, or -1 if unknown.  */
 
diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h
index c81b1a1..c18047a 100644
--- a/gcc/tree-ssanames.h
+++ b/gcc/tree-ssanames.h
@@ -74,6 +74,8 @@  extern void set_range_info (tree, enum value_range_type, const wide_int_ref &,
 extern enum value_range_type get_range_info (const_tree, wide_int *,
 					     wide_int *);
 extern void set_nonzero_bits (tree, const wide_int_ref &);
+extern void refine_range_info (tree name, const wide_int_ref &zeros,
+			       const wide_int_ref &ones);
 extern wide_int get_nonzero_bits (const_tree);
 extern bool ssa_name_has_boolean_range (tree);
 extern void init_ssanames (struct function *, int);