Message ID | 20170505153614.GC1809@tucnak |
---|---|
State | New |
Headers | show |
On May 5, 2017 5:36:14 PM GMT+02:00, Jakub Jelinek <jakub@redhat.com> wrote: >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? OK. Richard. >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. > > * 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
--- 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; +}