diff mbox series

Fix switchconv ICE (PR tree-optimization/84740)

Message ID 20180307215108.GN5867@tucnak
State New
Headers show
Series Fix switchconv ICE (PR tree-optimization/84740) | expand

Commit Message

Jakub Jelinek March 7, 2018, 9:51 p.m. UTC
Hi!

On the following testcase info.final_bb has only one PHI, the virtual one,
so info.phi_count is 0.  For info.phi_count == 0, we don't really create any
arrays etc.; just returning early (before create_temp_arrays) would work,
but would leave the useless GIMPLE_SWITCH in the IL and it would take many
passes to optimize it properly.  We know that all but the default: bbs are
really empty and the default: can do something arbitrary, if all the ranges
are consecutive, it is better to just let gen_inbound_check do its work
and convert the switch into if (cond) { former_default_bb }.
All but build_constructors function can handle 0 info.phi_count, but
build_constructors can't, on the other side doesn't need to do anything
if it is 0.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2018-03-07  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/84740
	* tree-switch-conversion.c (process_switch): Call build_constructors
	only if info.phi_count is non-zero.

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


	Jakub

Comments

Richard Biener March 8, 2018, 7:07 a.m. UTC | #1
On March 7, 2018 10:51:08 PM GMT+01:00, Jakub Jelinek <jakub@redhat.com> wrote:
>Hi!
>
>On the following testcase info.final_bb has only one PHI, the virtual
>one,
>so info.phi_count is 0.  For info.phi_count == 0, we don't really
>create any
>arrays etc.; just returning early (before create_temp_arrays) would
>work,
>but would leave the useless GIMPLE_SWITCH in the IL and it would take
>many
>passes to optimize it properly.  We know that all but the default: bbs
>are
>really empty and the default: can do something arbitrary, if all the
>ranges
>are consecutive, it is better to just let gen_inbound_check do its work
>and convert the switch into if (cond) { former_default_bb }.
>All but build_constructors function can handle 0 info.phi_count, but
>build_constructors can't, on the other side doesn't need to do anything
>if it is 0.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK. 

Richard. 

>2018-03-07  Jakub Jelinek  <jakub@redhat.com>
>
>	PR tree-optimization/84740
>	* tree-switch-conversion.c (process_switch): Call build_constructors
>	only if info.phi_count is non-zero.
>
>	* gcc.dg/torture/pr84740.c: New test.
>
>--- gcc/tree-switch-conversion.c.jj	2018-01-09 08:58:15.000000000 +0100
>+++ gcc/tree-switch-conversion.c	2018-03-07 12:03:42.228246408 +0100
>@@ -1563,7 +1563,8 @@ process_switch (gswitch *swtch)
>   gather_default_values (info.default_case_nonstandard
> 			 ? gimple_switch_label (swtch, 1)
> 			 : gimple_switch_default_label (swtch), &info);
>-  build_constructors (swtch, &info);
>+  if (info.phi_count)
>+    build_constructors (swtch, &info);
> 
>build_arrays (swtch, &info); /* Build the static arrays and
>assignments.   */
>   gen_inbound_check (swtch, &info);	/* Build the bounds check.  */
>--- gcc/testsuite/gcc.dg/torture/pr84740.c.jj	2018-03-07
>12:13:02.153271986 +0100
>+++ gcc/testsuite/gcc.dg/torture/pr84740.c	2018-03-07
>12:12:42.643270368 +0100
>@@ -0,0 +1,24 @@
>+/* PR tree-optimization/84740 */
>+
>+void
>+frobulate_for_gcc (unsigned int v)
>+{
>+  const char *s;
>+  switch (v)
>+    {
>+    case 0:
>+      s = "foo";
>+      break;
>+    case 1:
>+      s = "bar";
>+      break;
>+    case 2:
>+      s = "spam";
>+      break;
>+    default:
>+      s = (const char *) 0;
>+      break;
>+    }
>+  if (!s)
>+    __builtin_printf ("%s\n", s);
>+}
>
>	Jakub
diff mbox series

Patch

--- gcc/tree-switch-conversion.c.jj	2018-01-09 08:58:15.000000000 +0100
+++ gcc/tree-switch-conversion.c	2018-03-07 12:03:42.228246408 +0100
@@ -1563,7 +1563,8 @@  process_switch (gswitch *swtch)
   gather_default_values (info.default_case_nonstandard
 			 ? gimple_switch_label (swtch, 1)
 			 : gimple_switch_default_label (swtch), &info);
-  build_constructors (swtch, &info);
+  if (info.phi_count)
+    build_constructors (swtch, &info);
 
   build_arrays (swtch, &info); /* Build the static arrays and assignments.   */
   gen_inbound_check (swtch, &info);	/* Build the bounds check.  */
--- gcc/testsuite/gcc.dg/torture/pr84740.c.jj	2018-03-07 12:13:02.153271986 +0100
+++ gcc/testsuite/gcc.dg/torture/pr84740.c	2018-03-07 12:12:42.643270368 +0100
@@ -0,0 +1,24 @@ 
+/* PR tree-optimization/84740 */
+
+void
+frobulate_for_gcc (unsigned int v)
+{
+  const char *s;
+  switch (v)
+    {
+    case 0:
+      s = "foo";
+      break;
+    case 1:
+      s = "bar";
+      break;
+    case 2:
+      s = "spam";
+      break;
+    default:
+      s = (const char *) 0;
+      break;
+    }
+  if (!s)
+    __builtin_printf ("%s\n", s);
+}