re PR tree-optimization/80632 (error: invalid PHI argument with -O2)
authorJakub Jelinek <jakub@redhat.com>
Fri, 5 May 2017 16:02:44 +0000 (18:02 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 5 May 2017 16:02:44 +0000 (18:02 +0200)
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.

From-SVN: r247642

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr80632.c [new file with mode: 0644]
gcc/tree-switch-conversion.c

index 51471bfc8fefb16f16b1e597c32c7ffa1fde8fbe..a038415f918240cebd2682267da6a378209b7998 100644 (file)
@@ -1,5 +1,11 @@
 2017-05-05  Jakub Jelinek  <jakub@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.
+
        PR tree-optimization/80558
        * tree-vrp.c (extract_range_from_binary_expr_1): Optimize
        [x, y] op z into [x op, y op z] for op & or | if conditions
index 7a1b00207aedfd5ab342c8ab95ba6916f5e7ddb4..99c237bafb9276cfd41e51dfa893823beb8e9d02 100644 (file)
@@ -1,5 +1,8 @@
 2017-05-05  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/80632
+       * gcc.dg/pr80632.c: New test.
+
        PR tree-optimization/80558
        * gcc.dg/tree-ssa/vrp115.c: New test.
 
diff --git a/gcc/testsuite/gcc.dg/pr80632.c b/gcc/testsuite/gcc.dg/pr80632.c
new file mode 100644 (file)
index 0000000..0d3c7b3
--- /dev/null
@@ -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;
+}
index 14e605dc001071cf85dbe100ae400484305f48fc..0a2a84068a0a07cfd9f79c1eb17595ef208c4db0 100644 (file)
@@ -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 switch_conv_info *info)
       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_block bbf,
       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];