[PATCH] Fix dom SWITCH_EXPR optimization (PR middle-end/29584)

Jakub Jelinek jakub@redhat.com
Thu Nov 16 16:07:00 GMT 2006


Hi!

The attached testcase ICEs on x86_64-linux (and other targets) in 4.1,
where DOM forward propagates a void * variable into SWITCH_EXPR's condition
and the middle-end in many places relies on SWITCH_COND having an integral
type (e.g. add_case_node's
  min_value = TYPE_MIN_VALUE (type);
  max_value = TYPE_MAX_VALUE (type);
).  I think it is better to ensure SWITCH_COND has integral type than
changing the middle-end to handle weird types, after all the FEs ensure
that SWITCH_EXPR has been created with integral type.

While this testcase doesn't reproduce the problem on 4.2/4.3, the same
code is still there (though moved to a different function), just loop
optimizer chooses a different type for the IV (in 4.1 it chooses void *
over ulong, in 4.2 it chooses ulong over void *).

Ok for 4.3/4.2/4.1?

	Jakub
-------------- next part --------------
2006-11-16  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/29584
	* tree-ssa-dom.c (simplify_switch_and_lookup_avail_expr): Don't
	optimize if DEF doesn't have integral type.

	* gcc.dg/torture/pr29584.c: New test.

--- gcc/tree-ssa-dom.c.jj	2006-10-05 00:29:42.000000000 +0200
+++ gcc/tree-ssa-dom.c	2006-11-16 16:30:06.000000000 +0100
@@ -2216,7 +2216,9 @@ simplify_switch_and_lookup_avail_expr (t
 
 	      need_precision = TYPE_PRECISION (ti);
 	      fail = false;
-	      if (TYPE_UNSIGNED (to) && !TYPE_UNSIGNED (ti))
+	      if (! INTEGRAL_TYPE_P (ti))
+		fail = true;
+	      else if (TYPE_UNSIGNED (to) && !TYPE_UNSIGNED (ti))
 		fail = true;
 	      else if (!TYPE_UNSIGNED (to) && TYPE_UNSIGNED (ti))
 		need_precision += 1;
--- gcc/testsuite/gcc.dg/torture/pr29584.c.jj	2006-11-16 16:34:20.000000000 +0100
+++ gcc/testsuite/gcc.dg/torture/pr29584.c	2006-11-16 16:34:59.000000000 +0100
@@ -0,0 +1,28 @@
+/* PR middle-end/29584 */
+/* { dg-do compile } */
+
+extern void *foo1 (void);
+extern void foo2 (void);
+extern void foo3 (void *, void *);
+extern int foo4 (void);
+
+void
+bar (void)
+{
+  int i;
+  void *s;
+  for (i = 1; i < 4; i++)
+    {
+      if (foo4 ())
+	foo2 ();
+      switch (0x8000000UL + i * 0x400)
+	{
+	case 0x80000000UL ... 0x80000000UL + 0x3a000000UL - 1:
+	  s = 0;
+	  break;
+	default:
+	  s = foo1 ();
+	}
+      foo3 ((void *) (0x8000000UL + i * 0x400), s);
+    }
+}
-------------- next part --------------
2006-11-16  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/29584
	* tree-ssa-forwprop.c (simplify_switch_expr): Don't
	optimize if DEF doesn't have integral type.

	* gcc.dg/torture/pr29584.c: New test.

--- gcc/tree-ssa-forwprop.c.jj	2006-10-05 00:28:42.000000000 +0200
+++ gcc/tree-ssa-forwprop.c	2006-11-16 16:47:12.000000000 +0100
@@ -934,7 +934,9 @@ simplify_switch_expr (tree stmt)
 
 	      need_precision = TYPE_PRECISION (ti);
 	      fail = false;
-	      if (TYPE_UNSIGNED (to) && !TYPE_UNSIGNED (ti))
+	      if (! INTEGRAL_TYPE_P (ti))
+		fail = true;
+	      else if (TYPE_UNSIGNED (to) && !TYPE_UNSIGNED (ti))
 		fail = true;
 	      else if (!TYPE_UNSIGNED (to) && TYPE_UNSIGNED (ti))
 		need_precision += 1;
--- gcc/testsuite/gcc.dg/torture/pr29584.c.jj	2006-11-16 16:34:20.000000000 +0100
+++ gcc/testsuite/gcc.dg/torture/pr29584.c	2006-11-16 16:34:59.000000000 +0100
@@ -0,0 +1,28 @@
+/* PR middle-end/29584 */
+/* { dg-do compile } */
+
+extern void *foo1 (void);
+extern void foo2 (void);
+extern void foo3 (void *, void *);
+extern int foo4 (void);
+
+void
+bar (void)
+{
+  int i;
+  void *s;
+  for (i = 1; i < 4; i++)
+    {
+      if (foo4 ())
+	foo2 ();
+      switch (0x8000000UL + i * 0x400)
+	{
+	case 0x80000000UL ... 0x80000000UL + 0x3a000000UL - 1:
+	  s = 0;
+	  break;
+	default:
+	  s = foo1 ();
+	}
+      foo3 ((void *) (0x8000000UL + i * 0x400), s);
+    }
+}


More information about the Gcc-patches mailing list