Hi!

My recent switchconv changes allowed final_bb virtual phi to be present,
but kind of assumed that the vop will be marked for renaming, which
sometimes happened and sometimes didn't.
The following patch instead attempts to find out what .MEM_NN we need
(for switches without non-standard default: that is for any edges from the
switch or switch forwarders to final_bb, otherwise it is any edge except
the default: one).

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

2017-05-05  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/80632
        * tree-switch-conversion.c (struct switch_conv_info): Add target_vop
        field.
        (build_arrays): Initialize it for virtual phis.
        (fix_phi_nodes): Use it for virtual phis.

        * gcc.dg/pr80632.c: New test.

--- gcc/tree-switch-conversion.c.jj     2017-05-03 09:41:38.000000000 +0200
+++ gcc/tree-switch-conversion.c        2017-05-05 12:04:29.434702222 +0200
@@ -581,6 +581,9 @@ struct switch_conv_info
      switch expression is out of range.  */
   tree *target_outbound_names;
 
+  /* VOP SSA_NAME.  */
+  tree target_vop;
+
   /* The first load statement that loads a temporary from a new static array.
    */
   gimple *arr_ref_first;
@@ -1216,6 +1219,24 @@ build_arrays (gswitch *swtch, struct swi
       gphi *phi = gpi.phi ();
       if (!virtual_operand_p (gimple_phi_result (phi)))
        build_one_array (swtch, i++, arr_index_type, phi, tidx, info);
+      else
+       {
+         edge e;
+         edge_iterator ei;
+         FOR_EACH_EDGE (e, ei, info->switch_bb->succs)
+           {
+             if (e->dest == info->final_bb)
+               break;
+             if (!info->default_case_nonstandard
+                 || e->dest != info->default_bb)
+               {
+                 e = single_succ_edge (e->dest);
+                 break;
+               }
+           }
+         gcc_assert (e && e->dest == info->final_bb);
+         info->target_vop = PHI_ARG_DEF_FROM_EDGE (phi, e);
+       }
     }
 }
 
@@ -1279,7 +1300,7 @@ fix_phi_nodes (edge e1f, edge e2f, basic
       gphi *phi = gsi.phi ();
       tree inbound, outbound;
       if (virtual_operand_p (gimple_phi_result (phi)))
-       inbound = outbound = gimple_vop (cfun);
+       inbound = outbound = info->target_vop;
       else
        {
          inbound = info->target_inbound_names[i];
--- gcc/testsuite/gcc.dg/pr80632.c.jj   2017-05-05 12:13:25.126024275 +0200
+++ gcc/testsuite/gcc.dg/pr80632.c      2017-05-05 12:12:14.000000000 +0200
@@ -0,0 +1,35 @@
+/* PR tree-optimization/80632 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+extern int bar (void);
+extern void baz (void);
+int a;
+
+int
+foo (void)
+{
+  int c = 8;
+  if (bar ())
+    {
+      baz ();
+      switch (a)
+       {
+       case 0:
+         c = 1;
+         break;
+       case 1:
+         c = 0;
+         break;
+       case 2:
+         c = 0;
+         break;
+       case 3:
+         c = 0;
+         break;
+       default:
+         c = 1;
+       }
+    }
+  return c;
+}

        Jakub

Reply via email to