This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix PR 24141
- From: Diego Novillo <dnovillo at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 1 Oct 2005 10:14:29 -0400
- Subject: Fix PR 24141
We were forgetting to clear out the equivalence bitmap when creating an
anti-range as a last resource in vrp_meet. When vrp_meet cannot merge
two ranges, it tries to see if it can at least create the anti-range
~[0, 0] which is generally useful. So, if the two ranges are non-zero,
but have an empty intersection, it creates ~[0, 0].
But it was not clearing out the equivalence bitmap, causing an ICE later
on.
Bootstrapped and tested x86, ia64, x86_64 (minus libjava) and ppc64.
PR 24141
* tree-vrp.c (vrp_meet): Clear VR0->EQUIV when building a
non-null range as a last resort.
testsuite/
* gcc.c-torture/execute/pr24141.c: New test.
Index: tree-vrp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vrp.c,v
retrieving revision 2.57
diff -d -u -p -r2.57 tree-vrp.c
--- tree-vrp.c 16 Sep 2005 07:54:03 -0000 2.57
+++ tree-vrp.c 1 Oct 2005 00:36:29 -0000
@@ -3424,7 +3459,14 @@ no_meet:
&& !range_includes_zero_p (vr0)
&& !symbolic_range_p (vr1)
&& !range_includes_zero_p (vr1))
- set_value_range_to_nonnull (vr0, TREE_TYPE (vr0->min));
+ {
+ set_value_range_to_nonnull (vr0, TREE_TYPE (vr0->min));
+
+ /* Since this meet operation did not result from the meeting of
+ two equivalent names, VR0 cannot have any equivalences. */
+ if (vr0->equiv)
+ bitmap_clear (vr0->equiv);
+ }
else
set_value_range_to_varying (vr0);
}
Index: testsuite/gcc.c-torture/execute/pr24141.c
===================================================================
RCS file: testsuite/gcc.c-torture/execute/pr24141.c
diff -N testsuite/gcc.c-torture/execute/pr24141.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.c-torture/execute/pr24141.c 1 Oct 2005 00:36:30 -0000
@@ -0,0 +1,33 @@
+// reduced testcase, compile with -O2. Also, with --disable-checking
+// gcc produces wrong code.
+
+void abort (void);
+int i;
+
+void g (void)
+{
+ i = 1;
+}
+
+void f (int a, int b)
+{
+ int c = 0;
+ if (a == 0)
+ c = 1;
+ if (c)
+ return;
+ if (c == 1)
+ c = 0;
+ if (b == 0)
+ c = 1;
+ if (c)
+ g ();
+}
+
+int main (void)
+{
+ f (1, 0);
+ if (i != 1)
+ abort ();
+ return 0;
+}