Message ID | 20101102233811.GL29412@tyan-ft48-01.lab.bos.redhat.com |
---|---|
State | New |
Headers | show |
On Wed, Nov 3, 2010 at 12:38 AM, Jakub Jelinek <jakub@redhat.com> wrote: > Hi! > > As has been discussed in the PR, vectorizer relies on DCE being performed > after it and we thus get ICEs during expansion if -ftree-vectorize > -fno-tree-dce. This patch fixes it by making sure at least one DCE is > performed after {,slp} vectorization even if -fno-tree-dce. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? I don't like this solution and rather have this bug not fixed than in this way. I think what would be more sensible would be to perform a quick backward walk over the single loop BB for the versions and nuke all stmts with has_zero_uses (which should cover all pattern stmts we inserted). I think vect_loop_versioning is the only place that would need to do that. It would of course be nicer to avoid copying those in the first place or rewrite how pattern recognition is done (which is one of the more ugly pieces of the vectorizer), but that sounds harder. Thanks, Richard. > 2010-11-02 Jakub Jelinek <jakub@redhat.com> > > PR tree-optimization/46172 > * passes.c (init_optimization_passes): Add pass_dce_vect. > * tree-pass.h (pass_dce_vect): New extern. > * tree-ssa-dce.c (gate_dce_vect): New function. > (pass_dce_vect): New variable. > > * gcc.dg/vect/O1-pr46172.c: New test. > > --- gcc/passes.c.jj 2010-11-01 09:07:24.000000000 +0100 > +++ gcc/passes.c 2010-11-02 20:19:13.000000000 +0100 > @@ -914,6 +914,7 @@ init_optimization_passes (void) > NEXT_PASS (pass_predcom); > NEXT_PASS (pass_complete_unroll); > NEXT_PASS (pass_slp_vectorize); > + NEXT_PASS (pass_dce_vect); > NEXT_PASS (pass_parallelize_loops); > NEXT_PASS (pass_loop_prefetch); > NEXT_PASS (pass_iv_optimize); > --- gcc/tree-pass.h.jj 2010-10-07 19:45:22.000000000 +0200 > +++ gcc/tree-pass.h 2010-11-02 15:40:15.000000000 +0100 > @@ -391,6 +391,7 @@ extern struct gimple_opt_pass pass_build > extern struct gimple_opt_pass pass_dominator; > extern struct gimple_opt_pass pass_dce; > extern struct gimple_opt_pass pass_dce_loop; > +extern struct gimple_opt_pass pass_dce_vect; > extern struct gimple_opt_pass pass_cd_dce; > extern struct gimple_opt_pass pass_call_cdce; > extern struct gimple_opt_pass pass_merge_phi; > --- gcc/tree-ssa-dce.c.jj 2010-08-26 19:50:24.000000000 +0200 > +++ gcc/tree-ssa-dce.c 2010-11-02 20:19:01.000000000 +0100 > @@ -1507,6 +1507,14 @@ gate_dce (void) > return flag_tree_dce != 0; > } > > +static bool > +gate_dce_vect (void) > +{ > + /* The vectorizer relies on DCE being performed before expansion. */ > + return flag_tree_dce == 0 > + && (flag_tree_vectorize || flag_tree_slp_vectorize == 1); > +} > + > struct gimple_opt_pass pass_dce = > { > { > @@ -1545,6 +1553,25 @@ struct gimple_opt_pass pass_dce_loop = > } > }; > > +struct gimple_opt_pass pass_dce_vect = > +{ > + { > + GIMPLE_PASS, > + "dcevect", /* name */ > + gate_dce_vect, /* gate */ > + tree_ssa_dce_loop, /* execute */ > + NULL, /* sub */ > + NULL, /* next */ > + 0, /* static_pass_number */ > + TV_TREE_DCE, /* tv_id */ > + PROP_cfg | PROP_ssa, /* properties_required */ > + 0, /* properties_provided */ > + 0, /* properties_destroyed */ > + 0, /* todo_flags_start */ > + TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */ > + } > +}; > + > struct gimple_opt_pass pass_cd_dce = > { > { > --- gcc/testsuite/gcc.dg/vect/O1-pr46172.c.jj 2010-11-02 16:08:14.000000000 +0100 > +++ gcc/testsuite/gcc.dg/vect/O1-pr46172.c 2010-11-02 16:09:25.000000000 +0100 > @@ -0,0 +1,16 @@ > +/* PR tree-optimization/46172 */ > +/* { dg-do compile } */ > +/* { dg-options "-O -ftree-vectorize -fno-tree-dce" } */ > + > +extern short v[]; > + > +int foo (int x) > +{ > + int i; > + int s = 0; > + for (i = 0; i < x; i++) > + s += v[i] * v[i]; > + return s; > +} > + > +/* { dg-final { cleanup-tree-dump "vect" } } */ > > Jakub >
--- gcc/passes.c.jj 2010-11-01 09:07:24.000000000 +0100 +++ gcc/passes.c 2010-11-02 20:19:13.000000000 +0100 @@ -914,6 +914,7 @@ init_optimization_passes (void) NEXT_PASS (pass_predcom); NEXT_PASS (pass_complete_unroll); NEXT_PASS (pass_slp_vectorize); + NEXT_PASS (pass_dce_vect); NEXT_PASS (pass_parallelize_loops); NEXT_PASS (pass_loop_prefetch); NEXT_PASS (pass_iv_optimize); --- gcc/tree-pass.h.jj 2010-10-07 19:45:22.000000000 +0200 +++ gcc/tree-pass.h 2010-11-02 15:40:15.000000000 +0100 @@ -391,6 +391,7 @@ extern struct gimple_opt_pass pass_build extern struct gimple_opt_pass pass_dominator; extern struct gimple_opt_pass pass_dce; extern struct gimple_opt_pass pass_dce_loop; +extern struct gimple_opt_pass pass_dce_vect; extern struct gimple_opt_pass pass_cd_dce; extern struct gimple_opt_pass pass_call_cdce; extern struct gimple_opt_pass pass_merge_phi; --- gcc/tree-ssa-dce.c.jj 2010-08-26 19:50:24.000000000 +0200 +++ gcc/tree-ssa-dce.c 2010-11-02 20:19:01.000000000 +0100 @@ -1507,6 +1507,14 @@ gate_dce (void) return flag_tree_dce != 0; } +static bool +gate_dce_vect (void) +{ + /* The vectorizer relies on DCE being performed before expansion. */ + return flag_tree_dce == 0 + && (flag_tree_vectorize || flag_tree_slp_vectorize == 1); +} + struct gimple_opt_pass pass_dce = { { @@ -1545,6 +1553,25 @@ struct gimple_opt_pass pass_dce_loop = } }; +struct gimple_opt_pass pass_dce_vect = +{ + { + GIMPLE_PASS, + "dcevect", /* name */ + gate_dce_vect, /* gate */ + tree_ssa_dce_loop, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_TREE_DCE, /* tv_id */ + PROP_cfg | PROP_ssa, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */ + } +}; + struct gimple_opt_pass pass_cd_dce = { { --- gcc/testsuite/gcc.dg/vect/O1-pr46172.c.jj 2010-11-02 16:08:14.000000000 +0100 +++ gcc/testsuite/gcc.dg/vect/O1-pr46172.c 2010-11-02 16:09:25.000000000 +0100 @@ -0,0 +1,16 @@ +/* PR tree-optimization/46172 */ +/* { dg-do compile } */ +/* { dg-options "-O -ftree-vectorize -fno-tree-dce" } */ + +extern short v[]; + +int foo (int x) +{ + int i; + int s = 0; + for (i = 0; i < x; i++) + s += v[i] * v[i]; + return s; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */