summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-13 11:21:39 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-13 11:21:39 +0000
commit7d48cd66509d868ed161e41878839802f552027d (patch)
treebb828fb1d805b42eb14a3c239b82bce7717d3d6e
parent4db2b5770d262abedfb1e713628833af1665df11 (diff)
downloadgcc-7d48cd66509d868ed161e41878839802f552027d.tar.gz
2012-07-13 Richard Guenther <rguenther@suse.de>
PR tree-optimization/53922 * tree-vrp.c (value_inside_range): Change prototype to take min/max instead of value-range. (range_includes_zero_p): Likewise. Return the result from value_inside_range. (extract_range_from_binary_expr_1): Adjust to handle dont-know return value from range_includes_zero_p. (extract_range_from_unary_expr_1): Likewise. (compare_range_with_value): Likewise. (vrp_meet_1): Likewise. * gcc.dg/torture/pr53922.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@189461 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr53922.c22
-rw-r--r--gcc/tree-vrp.c78
4 files changed, 66 insertions, 52 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e900a2acaae..f7b303a9f3c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2012-07-13 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/53922
+ * tree-vrp.c (value_inside_range): Change prototype to take
+ min/max instead of value-range.
+ (range_includes_zero_p): Likewise. Return the result from
+ value_inside_range.
+ (extract_range_from_binary_expr_1): Adjust to handle dont-know
+ return value from range_includes_zero_p.
+ (extract_range_from_unary_expr_1): Likewise.
+ (compare_range_with_value): Likewise.
+ (vrp_meet_1): Likewise.
+
2012-07-13 Bill Schmidt <wschmidt@linux.ibm.com>
* doc/tm.texi: Regenerate.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0e2b8f30a5b..c6286636b14 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2012-07-13 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/53922
+ * gcc.dg/torture/pr53922.c: New testcase.
+
2012-07-13 Hans-Peter Nilsson <hp@axis.com>
PR rtl-optimization/53908
diff --git a/gcc/testsuite/gcc.dg/torture/pr53922.c b/gcc/testsuite/gcc.dg/torture/pr53922.c
new file mode 100644
index 00000000000..e42d1c788c7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr53922.c
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+/* { dg-require-weak "" } */
+
+int x(int a)
+{
+ return a;
+}
+int y(int a) __attribute__ ((weak));
+int g = 0;
+int main()
+{
+ int (*scan_func)(int);
+ if (g)
+ scan_func = x;
+ else
+ scan_func = y;
+
+ if (scan_func)
+ g = scan_func(10);
+
+ return 0;
+}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 32c5afa49c7..0ce9a74c271 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1339,41 +1339,25 @@ compare_values (tree val1, tree val2)
}
-/* Return 1 if VAL is inside value range VR (VR->MIN <= VAL <= VR->MAX),
- 0 if VAL is not inside VR,
+/* Return 1 if VAL is inside value range MIN <= VAL <= MAX,
+ 0 if VAL is not inside [MIN, MAX],
-2 if we cannot tell either way.
- FIXME, the current semantics of this functions are a bit quirky
- when taken in the context of VRP. In here we do not care
- about VR's type. If VR is the anti-range ~[3, 5] the call
- value_inside_range (4, VR) will return 1.
-
- This is counter-intuitive in a strict sense, but the callers
- currently expect this. They are calling the function
- merely to determine whether VR->MIN <= VAL <= VR->MAX. The
- callers are applying the VR_RANGE/VR_ANTI_RANGE semantics
- themselves.
-
- This also applies to value_ranges_intersect_p and
- range_includes_zero_p. The semantics of VR_RANGE and
- VR_ANTI_RANGE should be encoded here, but that also means
- adapting the users of these functions to the new semantics.
-
Benchmark compile/20001226-1.c compilation time after changing this
function. */
static inline int
-value_inside_range (tree val, value_range_t * vr)
+value_inside_range (tree val, tree min, tree max)
{
int cmp1, cmp2;
- cmp1 = operand_less_p (val, vr->min);
+ cmp1 = operand_less_p (val, min);
if (cmp1 == -2)
return -2;
if (cmp1 == 1)
return 0;
- cmp2 = operand_less_p (vr->max, val);
+ cmp2 = operand_less_p (max, val);
if (cmp2 == -2)
return -2;
@@ -1402,23 +1386,14 @@ value_ranges_intersect_p (value_range_t *vr0, value_range_t *vr1)
}
-/* Return true if VR includes the value zero, false otherwise. FIXME,
- currently this will return false for an anti-range like ~[-4, 3].
- This will be wrong when the semantics of value_inside_range are
- modified (currently the users of this function expect these
- semantics). */
+/* Return 1 if [MIN, MAX] includes the value zero, 0 if it does not
+ include the value zero, -2 if we cannot tell. */
-static inline bool
-range_includes_zero_p (value_range_t *vr)
+static inline int
+range_includes_zero_p (tree min, tree max)
{
- tree zero;
-
- gcc_assert (vr->type != VR_UNDEFINED
- && vr->type != VR_VARYING
- && !symbolic_range_p (vr));
-
- zero = build_int_cst (TREE_TYPE (vr->min), 0);
- return (value_inside_range (zero, vr) == 1);
+ tree zero = build_int_cst (TREE_TYPE (min), 0);
+ return value_inside_range (zero, min, max);
}
/* Return true if *VR is know to only contain nonnegative values. */
@@ -2641,7 +2616,7 @@ extract_range_from_binary_expr_1 (value_range_t *vr,
gives [min / 4, max / 4] range. */
if (vr1.type == VR_RANGE
&& !symbolic_range_p (&vr1)
- && !range_includes_zero_p (&vr1))
+ && range_includes_zero_p (vr1.min, vr1.max) == 0)
{
vr0.type = type = VR_RANGE;
vr0.min = vrp_val_min (expr_type);
@@ -2658,8 +2633,7 @@ extract_range_from_binary_expr_1 (value_range_t *vr,
not eliminate a division by zero. */
if (cfun->can_throw_non_call_exceptions
&& (vr1.type != VR_RANGE
- || symbolic_range_p (&vr1)
- || range_includes_zero_p (&vr1)))
+ || range_includes_zero_p (vr1.min, vr1.max) != 0))
{
set_value_range_to_varying (vr);
return;
@@ -2670,8 +2644,7 @@ extract_range_from_binary_expr_1 (value_range_t *vr,
include 0. */
if (vr0.type == VR_RANGE
&& (vr1.type != VR_RANGE
- || symbolic_range_p (&vr1)
- || range_includes_zero_p (&vr1)))
+ || range_includes_zero_p (vr1.min, vr1.max) != 0))
{
tree zero = build_int_cst (TREE_TYPE (vr0.min), 0);
int cmp;
@@ -2723,8 +2696,7 @@ extract_range_from_binary_expr_1 (value_range_t *vr,
else if (code == TRUNC_MOD_EXPR)
{
if (vr1.type != VR_RANGE
- || symbolic_range_p (&vr1)
- || range_includes_zero_p (&vr1)
+ || range_includes_zero_p (vr1.min, vr1.max) != 0
|| vrp_val_is_min (vr1.min))
{
set_value_range_to_varying (vr);
@@ -3159,7 +3131,7 @@ extract_range_from_unary_expr_1 (value_range_t *vr,
~[-INF, min(MIN, MAX)]. */
if (vr0.type == VR_ANTI_RANGE)
{
- if (range_includes_zero_p (&vr0))
+ if (range_includes_zero_p (vr0.min, vr0.max) == 1)
{
/* Take the lower of the two values. */
if (cmp != 1)
@@ -3210,7 +3182,7 @@ extract_range_from_unary_expr_1 (value_range_t *vr,
/* If the range contains zero then we know that the minimum value in the
range will be zero. */
- else if (range_includes_zero_p (&vr0))
+ else if (range_includes_zero_p (vr0.min, vr0.max) == 1)
{
if (cmp == 1)
max = min;
@@ -3812,7 +3784,7 @@ compare_range_with_value (enum tree_code comp, value_range_t *vr, tree val,
return NULL_TREE;
/* ~[VAL_1, VAL_2] OP VAL is known if VAL_1 <= VAL <= VAL_2. */
- if (value_inside_range (val, vr) == 1)
+ if (value_inside_range (val, vr->min, vr->max) == 1)
return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node;
return NULL_TREE;
@@ -7548,12 +7520,14 @@ vrp_meet_1 (value_range_t *vr0, value_range_t *vr1)
anti-range. FIXME, all this nonsense about distinguishing
anti-ranges from ranges is necessary because of the odd
semantics of range_includes_zero_p and friends. */
- if (!symbolic_range_p (&saved)
- && ((saved.type == VR_RANGE && !range_includes_zero_p (&saved))
- || (saved.type == VR_ANTI_RANGE && range_includes_zero_p (&saved)))
- && !symbolic_range_p (vr1)
- && ((vr1->type == VR_RANGE && !range_includes_zero_p (vr1))
- || (vr1->type == VR_ANTI_RANGE && range_includes_zero_p (vr1))))
+ if (((saved.type == VR_RANGE
+ && range_includes_zero_p (saved.min, saved.max) == 0)
+ || (saved.type == VR_ANTI_RANGE
+ && range_includes_zero_p (saved.min, saved.max) == 1))
+ && ((vr1->type == VR_RANGE
+ && range_includes_zero_p (vr1->min, vr1->max) == 0)
+ || (vr1->type == VR_ANTI_RANGE
+ && range_includes_zero_p (vr1->min, vr1->max) == 1)))
{
set_value_range_to_nonnull (vr0, TREE_TYPE (saved.min));