aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2012-06-19 13:06:35 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2012-06-19 13:06:35 +0000
commit105b7208d1f4630a29c09c31b5273b1c602a04c1 (patch)
treef2c02a77b95275c93238479fe3e13a1e15cb5f83 /gcc
parentaf4d0d913bb41215875b7e9e668009ba98d973e6 (diff)
downloadgcc-105b7208d1f4630a29c09c31b5273b1c602a04c1.zip
gcc-105b7208d1f4630a29c09c31b5273b1c602a04c1.tar.gz
gcc-105b7208d1f4630a29c09c31b5273b1c602a04c1.tar.bz2
tree-vrp.c (intersect_ranges): Handle more cases.
2012-06-19 Richard Guenther <rguenther@suse.de> * tree-vrp.c (intersect_ranges): Handle more cases. (vrp_intersect_ranges): Dump what we intersect and call ... (vrp_intersect_ranges_1): ... this. From-SVN: r188776
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/tree-vrp.c151
2 files changed, 134 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index df128a4..9b96131 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2012-06-19 Richard Guenther <rguenther@suse.de>
+ * tree-vrp.c (intersect_ranges): Handle more cases.
+ (vrp_intersect_ranges): Dump what we intersect and call ...
+ (vrp_intersect_ranges_1): ... this.
+
+2012-06-19 Richard Guenther <rguenther@suse.de>
+
PR tree-optimization/53708
* tree-vect-data-refs.c (vect_can_force_dr_alignment_p): Preserve
user-supplied alignment and alignment of decls with the used
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 1147552..53d6ac3 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -6781,9 +6781,31 @@ intersect_ranges (enum value_range_type *vr0type,
enum value_range_type vr1type,
tree vr1min, tree vr1max)
{
+ bool mineq = operand_equal_p (*vr0min, vr1min, 0);
+ bool maxeq = operand_equal_p (*vr0max, vr1max, 0);
+
/* [] is vr0, () is vr1 in the following classification comments. */
- if (operand_less_p (*vr0max, vr1min) == 1
- || operand_less_p (vr1max, *vr0min) == 1)
+ if (mineq && maxeq)
+ {
+ /* [( )] */
+ if (*vr0type == vr1type)
+ /* Nothing to do for equal ranges. */
+ ;
+ else if ((*vr0type == VR_RANGE
+ && vr1type == VR_ANTI_RANGE)
+ || (*vr0type == VR_ANTI_RANGE
+ && vr1type == VR_RANGE))
+ {
+ /* For anti-range with range intersection the result is empty. */
+ *vr0type = VR_UNDEFINED;
+ *vr0min = NULL_TREE;
+ *vr0max = NULL_TREE;
+ }
+ else
+ gcc_unreachable ();
+ }
+ else if (operand_less_p (*vr0max, vr1min) == 1
+ || operand_less_p (vr1max, *vr0min) == 1)
{
/* [ ] ( ) or ( ) [ ]
If the ranges have an empty intersection, the result of the
@@ -6813,19 +6835,48 @@ intersect_ranges (enum value_range_type *vr0type,
/* Take VR0. */
}
}
- else if (operand_less_p (vr1max, *vr0max) == 1
- && operand_less_p (*vr0min, vr1min) == 1)
+ else if ((maxeq || operand_less_p (vr1max, *vr0max) == 1)
+ && (mineq || operand_less_p (*vr0min, vr1min) == 1))
{
- /* [ ( ) ] */
- if (*vr0type == VR_RANGE)
+ /* [ ( ) ] or [( ) ] or [ ( )] */
+ if (*vr0type == VR_RANGE
+ && vr1type == VR_RANGE)
{
- /* If the outer is a range choose the inner one.
- ??? If the inner is an anti-range this arbitrarily chooses
- the anti-range. */
+ /* If both are ranges the result is the inner one. */
*vr0type = vr1type;
*vr0min = vr1min;
*vr0max = vr1max;
}
+ else if (*vr0type == VR_RANGE
+ && vr1type == VR_ANTI_RANGE)
+ {
+ /* Choose the right gap if the left one is empty. */
+ if (mineq)
+ {
+ if (TREE_CODE (vr1max) == INTEGER_CST)
+ *vr0min = int_const_binop (PLUS_EXPR, vr1max, integer_one_node);
+ else
+ *vr0min = vr1max;
+ }
+ /* Choose the left gap if the right one is empty. */
+ else if (maxeq)
+ {
+ if (TREE_CODE (vr1min) == INTEGER_CST)
+ *vr0max = int_const_binop (MINUS_EXPR, vr1min,
+ integer_one_node);
+ else
+ *vr0max = vr1min;
+ }
+ /* Choose the anti-range if the range is effectively varying. */
+ else if (vrp_val_is_min (*vr0min)
+ && vrp_val_is_max (*vr0max))
+ {
+ *vr0type = vr1type;
+ *vr0min = vr1min;
+ *vr0max = vr1max;
+ }
+ /* Else choose the range. */
+ }
else if (*vr0type == VR_ANTI_RANGE
&& vr1type == VR_ANTI_RANGE)
/* If both are anti-ranges the result is the outer one. */
@@ -6841,16 +6892,52 @@ intersect_ranges (enum value_range_type *vr0type,
else
gcc_unreachable ();
}
- else if (operand_less_p (*vr0max, vr1max) == 1
- && operand_less_p (vr1min, *vr0min) == 1)
+ else if ((maxeq || operand_less_p (*vr0max, vr1max) == 1)
+ && (mineq || operand_less_p (vr1min, *vr0min) == 1))
{
- /* ( [ ] ) */
- if (vr1type == VR_RANGE)
- /* If the outer is a range, choose the inner one.
- ??? If the inner is an anti-range this arbitrarily chooses
- the anti-range. */
+ /* ( [ ] ) or ([ ] ) or ( [ ]) */
+ if (*vr0type == VR_RANGE
+ && vr1type == VR_RANGE)
+ /* Choose the inner range. */
;
else if (*vr0type == VR_ANTI_RANGE
+ && vr1type == VR_RANGE)
+ {
+ /* Choose the right gap if the left is empty. */
+ if (mineq)
+ {
+ *vr0type = VR_RANGE;
+ if (TREE_CODE (*vr0max) == INTEGER_CST)
+ *vr0min = int_const_binop (PLUS_EXPR, *vr0max,
+ integer_one_node);
+ else
+ *vr0min = *vr0max;
+ *vr0max = vr1max;
+ }
+ /* Choose the left gap if the right is empty. */
+ else if (maxeq)
+ {
+ *vr0type = VR_RANGE;
+ if (TREE_CODE (*vr0min) == INTEGER_CST)
+ *vr0max = int_const_binop (MINUS_EXPR, *vr0min,
+ integer_one_node);
+ else
+ *vr0max = *vr0min;
+ *vr0min = vr1min;
+ }
+ /* Choose the anti-range if the range is effectively varying. */
+ else if (vrp_val_is_min (vr1min)
+ && vrp_val_is_max (vr1max))
+ ;
+ /* Else choose the range. */
+ else
+ {
+ *vr0type = vr1type;
+ *vr0min = vr1min;
+ *vr0max = vr1max;
+ }
+ }
+ else if (*vr0type == VR_ANTI_RANGE
&& vr1type == VR_ANTI_RANGE)
{
/* If both are anti-ranges the result is the outer one. */
@@ -6871,10 +6958,9 @@ intersect_ranges (enum value_range_type *vr0type,
}
else if ((operand_less_p (vr1min, *vr0max) == 1
|| operand_equal_p (vr1min, *vr0max, 0))
- && (operand_less_p (*vr0min, vr1min) == 1
- || operand_equal_p (*vr0min, vr1min, 0)))
+ && operand_less_p (*vr0min, vr1min) == 1)
{
- /* [ ( ] ) */
+ /* [ ( ] ) or [ ]( ) */
if (*vr0type == VR_ANTI_RANGE
&& vr1type == VR_ANTI_RANGE)
*vr0max = vr1max;
@@ -6906,10 +6992,9 @@ intersect_ranges (enum value_range_type *vr0type,
}
else if ((operand_less_p (*vr0min, vr1max) == 1
|| operand_equal_p (*vr0min, vr1max, 0))
- && (operand_less_p (vr1min, *vr0min) == 1
- || operand_equal_p (vr1min, *vr0min, 0)))
+ && operand_less_p (vr1min, *vr0min) == 1)
{
- /* ( [ ) ] */
+ /* ( [ ) ] or ( )[ ] */
if (*vr0type == VR_ANTI_RANGE
&& vr1type == VR_ANTI_RANGE)
*vr0min = vr1min;
@@ -6952,7 +7037,7 @@ intersect_ranges (enum value_range_type *vr0type,
in *VR0. This may not be the smallest possible such range. */
static void
-vrp_intersect_ranges (value_range_t *vr0, value_range_t *vr1)
+vrp_intersect_ranges_1 (value_range_t *vr0, value_range_t *vr1)
{
value_range_t saved;
@@ -7003,6 +7088,26 @@ vrp_intersect_ranges (value_range_t *vr0, value_range_t *vr1)
bitmap_copy (vr0->equiv, vr1->equiv);
}
+static void
+vrp_intersect_ranges (value_range_t *vr0, value_range_t *vr1)
+{
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Intersecting\n ");
+ dump_value_range (dump_file, vr0);
+ fprintf (dump_file, "\nand\n ");
+ dump_value_range (dump_file, vr1);
+ fprintf (dump_file, "\n");
+ }
+ vrp_intersect_ranges_1 (vr0, vr1);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "to\n ");
+ dump_value_range (dump_file, vr0);
+ fprintf (dump_file, "\n");
+ }
+}
+
/* Meet operation for value ranges. Given two value ranges VR0 and
VR1, store in VR0 a range that contains both VR0 and VR1. This
may not be the smallest possible such range. */