This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[committed] Fix VRP range meet (PR tree-optimization/59358)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 2 Dec 2013 23:47:02 +0100
- Subject: [committed] Fix VRP range meet (PR tree-optimization/59358)
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
The following testcase is miscompiled (to endless loop), because
union_ranges didn't count with the possibility that *vr0max and vr1max
are uncomparable (one of them is symbolic).
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
preapproved by richi on IRC, committed to trunk/4.8.
2013-12-02 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/59358
* tree-vrp.c (union_ranges): To check for the partially
overlapping ranges or adjacent ranges, also compare *vr0max
with vr1max.
* gcc.c-torture/execute/pr59358.c: New test.
--- gcc/tree-vrp.c.jj 2013-11-28 23:51:58.000000000 +0100
+++ gcc/tree-vrp.c 2013-12-02 13:24:10.750956769 +0100
@@ -7758,7 +7758,8 @@ union_ranges (enum value_range_type *vr0
}
else if ((operand_less_p (vr1min, *vr0max) == 1
|| operand_equal_p (vr1min, *vr0max, 0))
- && operand_less_p (*vr0min, vr1min) == 1)
+ && operand_less_p (*vr0min, vr1min) == 1
+ && operand_less_p (*vr0max, vr1max) == 1)
{
/* [ ( ] ) or [ ]( ) */
if (*vr0type == VR_RANGE
@@ -7792,7 +7793,8 @@ union_ranges (enum value_range_type *vr0
}
else if ((operand_less_p (*vr0min, vr1max) == 1
|| operand_equal_p (*vr0min, vr1max, 0))
- && operand_less_p (vr1min, *vr0min) == 1)
+ && operand_less_p (vr1min, *vr0min) == 1
+ && operand_less_p (vr1max, *vr0max) == 1)
{
/* ( [ ) ] or ( )[ ] */
if (*vr0type == VR_RANGE
--- gcc/testsuite/gcc.c-torture/execute/pr59358.c.jj 2013-12-02 13:26:33.984198815 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr59358.c 2013-12-02 13:26:17.000000000 +0100
@@ -0,0 +1,44 @@
+/* PR tree-optimization/59358 */
+
+__attribute__((noinline, noclone)) int
+foo (int *x, int y)
+{
+ int z = *x;
+ if (y > z && y <= 16)
+ while (y > z)
+ z *= 2;
+ return z;
+}
+
+int
+main ()
+{
+ int i;
+ for (i = 1; i < 17; i++)
+ {
+ int j = foo (&i, 16);
+ int k;
+ if (i >= 8 && i <= 15)
+ k = 16 + (i - 8) * 2;
+ else if (i >= 4 && i <= 7)
+ k = 16 + (i - 4) * 4;
+ else if (i == 3)
+ k = 24;
+ else
+ k = 16;
+ if (j != k)
+ __builtin_abort ();
+ j = foo (&i, 7);
+ if (i >= 7)
+ k = i;
+ else if (i >= 4)
+ k = 8 + (i - 4) * 2;
+ else if (i == 3)
+ k = 12;
+ else
+ k = 8;
+ if (j != k)
+ __builtin_abort ();
+ }
+ return 0;
+}
Jakub