On Tue, 1 Dec 2015, Alan Lawrence wrote: > This follows on from discussion at > https://gcc.gnu.org/ml/gcc-patches/2015-11/msg03392.html > To recap: Starting in r229479 and continuing until at least 229711, compiling > polynom.c from spec2000 on aarch64-none-linux-gnu, with options > -O3 -mcpu=cortex-a53 -ffast-math (on both cross, native bootstrapped, and > native > --disable-bootstrap compilers), produced a verify_gimple ICE after unswitch: > > ../spec2000/benchspec/CINT2000/254.gap/src/polynom.c: In function > 'NormalizeCoeffsListx': > ../spec2000/benchspec/CINT2000/254.gap/src/polynom.c:358:11: error: > incompatible types in PHI argument 0 > TypHandle NormalizeCoeffsListx ( hdC ) > ^ > long int > > int > > ../spec2000/benchspec/CINT2000/254.gap/src/polynom.c:358:11: error: location > references block not in block tree > l1_279 = PHI <1(28), l1_299(33)> > ../spec2000/benchspec/CINT2000/254.gap/src/polynom.c:358:11: error: invalid > PHI argument > > ../spec2000/benchspec/CINT2000/254.gap/src/polynom.c:358:11: internal > compiler error: tree check: expected class 'type', have 'declaration' > (namespace_decl) in useless_type_conversion_p, at gimple-expr.c:84 > 0xd110ef tree_class_check_failed(tree_node const*, tree_code_class, char > const*, int, char const*) > ../../gcc-fsf/gcc/tree.c:9643 > 0x82561b tree_class_check > ../../gcc-fsf/gcc/tree.h:3042 > 0x82561b useless_type_conversion_p(tree_node*, tree_node*) > ../../gcc-fsf/gcc/gimple-expr.c:84 > 0xaca043 verify_gimple_phi > ../../gcc-fsf/gcc/tree-cfg.c:4673 > 0xaca043 verify_gimple_in_cfg(function*, bool) > ../../gcc-fsf/gcc/tree-cfg.c:4967 > 0x9c2e0b execute_function_todo > ../../gcc-fsf/gcc/passes.c:1967 > 0x9c360b do_per_function > ../../gcc-fsf/gcc/passes.c:1659 > 0x9c3807 execute_todo > ../../gcc-fsf/gcc/passes.c:2022 > > I was not able to reduce the testcase below about 30k characters, with e.g. > #define T_VOID 0 > .... T_VOID .... > producing the ICE, but manually changing to > .... 0 .... > preventing the ICE; as did running the preprocessor as a separate step, or a > wide variety of options (e.g. -fdump-tree-alias). > > In the end I traced this to loop_unswitch reading stale values from the edge > redirect map, which is keyed on 'edge' (a pointer to struct edge_def); the map > entries had been left there by pass_dominator (on a different function), and > by > "chance" the edge *pointers* were the same as to some current edge_defs (even > though they pointed to structures created by different allocations, the first > of which had since been freed). Hence the fragility of the testcase and > environment. > > While the ICE is prevented merely by adding a call to > redirect_edge_var_map_destroy at the end of pass_dominator::execute, given the > fragility of the bug, difficulty of reducing the testcase, and the low > overhead > of emptying an already-empty map, I believe the right fix is to empty the map > as often as can correctly do so, hence this patch - based substantially on > Richard's comments in PR/68117. > > Bootstrapped + check-gcc + check-g++ on x86_64 linux, based on r231105; I've > also built SPEC2000 on aarch64-none-linux-gnu by applying this patch (roughly) > onto the previously-failing r229711, which also passes aarch64 bootstrap, and > a more recent bootstrap on aarch64 is ongoing. Assuming/if no regressions > there... > > Is this ok for trunk? > > This could also be a candidate for the 5.3 release; backporting depends only > on > the (fairly trivial) r230357.
Looks good to me (for both, but backport only after 5.3 is released). But please wait for the discussion with Jeff to settle down. Thanks, Richard. > gcc/ChangeLog: > > <DATE> Alan Lawrence <alan.lawre...@arm.com> > Richard Biener <richard.guent...@gmail.com> > > * cfgexpand.c (pass_expand::execute): Replace call to > redirect_edge_var_map_destroy with redirect_edge_var_map_empty. > * tree-ssa.c (delete_tree_ssa): Likewise. > * function.c (set_cfun): Call redirect_edge_var_map_empty. > * passes.c (execute_one_ipa_transform_pass, execute_one_pass): Likewise. > * tree-ssa.h (redirect_edge_var_map_destroy): Remove. > (redirect_edge_var_map_empty): New. > * tree-ssa.c (redirect_edge_var_map_destroy): Remove. > (redirect_edge_var_map_empty): New. > > --- > gcc/cfgexpand.c | 2 +- > gcc/function.c | 2 ++ > gcc/passes.c | 2 ++ > gcc/tree-ssa.c | 8 ++++---- > gcc/tree-ssa.h | 2 +- > 5 files changed, 10 insertions(+), 6 deletions(-) > > diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c > index 1990e10..ede1b82 100644 > --- a/gcc/cfgexpand.c > +++ b/gcc/cfgexpand.c > @@ -6291,7 +6291,7 @@ pass_expand::execute (function *fun) > expand_phi_nodes (&SA); > > /* Release any stale SSA redirection data. */ > - redirect_edge_var_map_destroy (); > + redirect_edge_var_map_empty (); > > /* Register rtl specific functions for cfg. */ > rtl_register_cfg_hooks (); > diff --git a/gcc/function.c b/gcc/function.c > index 515d7c0..e452865 100644 > --- a/gcc/function.c > +++ b/gcc/function.c > @@ -75,6 +75,7 @@ along with GCC; see the file COPYING3. If not see > #include "tree-chkp.h" > #include "rtl-chkp.h" > #include "tree-dfa.h" > +#include "tree-ssa.h" > > /* So we can assign to cfun in this file. */ > #undef cfun > @@ -4798,6 +4799,7 @@ set_cfun (struct function *new_cfun) > { > cfun = new_cfun; > invoke_set_current_function_hook (new_cfun ? new_cfun->decl : > NULL_TREE); > + redirect_edge_var_map_empty (); > } > } > > diff --git a/gcc/passes.c b/gcc/passes.c > index 0e23dcb..ba9bfc2 100644 > --- a/gcc/passes.c > +++ b/gcc/passes.c > @@ -2218,6 +2218,7 @@ execute_one_ipa_transform_pass (struct cgraph_node > *node, > pass_fini_dump_file (pass); > > current_pass = NULL; > + redirect_edge_var_map_empty (); > > /* Signal this is a suitable GC collection point. */ > if (!(todo_after & TODO_do_not_ggc_collect)) > @@ -2370,6 +2371,7 @@ execute_one_pass (opt_pass *pass) > || pass->type != RTL_PASS); > > current_pass = NULL; > + redirect_edge_var_map_empty (); > > if (todo_after & TODO_discard_function) > { > diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c > index 02fca4c..ddc7a65 100644 > --- a/gcc/tree-ssa.c > +++ b/gcc/tree-ssa.c > @@ -119,10 +119,10 @@ redirect_edge_var_map_vector (edge e) > /* Clear the edge variable mappings. */ > > void > -redirect_edge_var_map_destroy (void) > +redirect_edge_var_map_empty (void) > { > - delete edge_var_maps; > - edge_var_maps = NULL; > + if (edge_var_maps) > + edge_var_maps->empty (); > } > > > @@ -1128,7 +1128,7 @@ delete_tree_ssa (struct function *fn) > fn->gimple_df = NULL; > > /* We no longer need the edge variable maps. */ > - redirect_edge_var_map_destroy (); > + redirect_edge_var_map_empty (); > } > > /* Return true if EXPR is a useless type conversion, otherwise return > diff --git a/gcc/tree-ssa.h b/gcc/tree-ssa.h > index 3b5bd70..d33eb9c 100644 > --- a/gcc/tree-ssa.h > +++ b/gcc/tree-ssa.h > @@ -35,7 +35,7 @@ extern void redirect_edge_var_map_add (edge, tree, tree, > source_location); > extern void redirect_edge_var_map_clear (edge); > extern void redirect_edge_var_map_dup (edge, edge); > extern vec<edge_var_map> *redirect_edge_var_map_vector (edge); > -extern void redirect_edge_var_map_destroy (void); > +extern void redirect_edge_var_map_empty (void); > extern edge ssa_redirect_edge (edge, basic_block); > extern void flush_pending_stmts (edge); > extern void gimple_replace_ssa_lhs (gimple *, tree); > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)