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.vivekanandara...@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 --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);