Bernd Edlinger <bernd.edlin...@hotmail.de> writes: >> How about this patch for the big comment? >> > > The comment should say that target_set_current_function() > cannot call target_reinit() because: > > target_reinit()=>lang_dependent_init_target() > =>init_optabs()=>init_all_optabs(this_fn_optabs); > > uses this_fn_optabs which is undefined here. > > However many targets (nios2, rx, i386, rs6000) do exactly that. > > Is there currently any target, that sets this_target_optab in the > target_set_current_function?
MIPS :-) (via save_target_globals_default_opts=>save_target_globals) I think other targets need to do the same thing in order for tests like that extended intrinsics_4.c to work. How does this patch look? Tested on x86_64-linux-gnu. I didn't remove save_target_globals_default_opts because there the temporary optimization_current_node also protects a call to init_reg_sets. Thanks, Richard gcc/ PR target/58115 * target-globals.c (save_target_globals): Remove this_fn_optab handling. * toplev.c: Include optabs.h. (target_reinit): Temporarily restore the global options if another set of options are in force. gcc/testsuite/ * gcc.target/i386/intrinsics_4.c (bar): New function. Index: gcc/target-globals.c =================================================================== --- gcc/target-globals.c 2014-01-02 22:16:03.042278971 +0000 +++ gcc/target-globals.c 2014-01-07 12:08:33.569900970 +0000 @@ -68,7 +68,6 @@ struct target_globals * save_target_globals (void) { struct target_globals *g; - struct target_optabs *saved_this_fn_optabs = this_fn_optabs; g = ggc_alloc_target_globals (); g->flag_state = XCNEW (struct target_flag_state); @@ -88,10 +87,8 @@ save_target_globals (void) g->bb_reorder = XCNEW (struct target_bb_reorder); g->lower_subreg = XCNEW (struct target_lower_subreg); restore_target_globals (g); - this_fn_optabs = this_target_optabs; init_reg_sets (); target_reinit (); - this_fn_optabs = saved_this_fn_optabs; return g; } Index: gcc/toplev.c =================================================================== --- gcc/toplev.c 2014-01-07 08:11:43.888058805 +0000 +++ gcc/toplev.c 2014-01-07 12:10:19.448096479 +0000 @@ -78,6 +78,7 @@ Software Foundation; either version 3, o #include "diagnostic-color.h" #include "context.h" #include "pass_manager.h" +#include "optabs.h" #if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) #include "dbxout.h" @@ -1752,6 +1753,23 @@ target_reinit (void) { struct rtl_data saved_x_rtl; rtx *saved_regno_reg_rtx; + tree saved_optimization_current_node; + struct target_optabs *saved_this_fn_optabs; + + /* Temporarily switch to the default optimization node, so that + *this_target_optabs is set to the default, not reflecting + whatever a previous function used for the optimize + attribute. */ + saved_optimization_current_node = optimization_current_node; + saved_this_fn_optabs = this_fn_optabs; + if (saved_optimization_current_node != optimization_default_node) + { + optimization_current_node = optimization_default_node; + cl_optimization_restore + (&global_options, + TREE_OPTIMIZATION (optimization_default_node)); + } + this_fn_optabs = this_target_optabs; /* Save *crtl and regno_reg_rtx around the reinitialization to allow target_reinit being called even after prepare_function_start. */ @@ -1769,7 +1787,16 @@ target_reinit (void) /* Reinitialize lang-dependent parts. */ lang_dependent_init_target (); - /* And restore it at the end, as free_after_compilation from + /* Restore the original optimization node. */ + if (saved_optimization_current_node != optimization_default_node) + { + optimization_current_node = saved_optimization_current_node; + cl_optimization_restore (&global_options, + TREE_OPTIMIZATION (optimization_current_node)); + } + this_fn_optabs = saved_this_fn_optabs; + + /* Restore regno_reg_rtx at the end, as free_after_compilation from expand_dummy_function_end clears it. */ if (saved_regno_reg_rtx) { Index: gcc/testsuite/gcc.target/i386/intrinsics_4.c =================================================================== --- gcc/testsuite/gcc.target/i386/intrinsics_4.c 2013-06-27 22:30:03.877275875 +0100 +++ gcc/testsuite/gcc.target/i386/intrinsics_4.c 2014-01-07 08:15:51.509627927 +0000 @@ -12,3 +12,10 @@ foo (void) { a[0] = _mm256_and_ps (b[0], c[0]); } + +/* Try again with a combination of target and optimization attributes. */ +void __attribute__((target ("avx"), optimize(3))) +bar (void) +{ + a[0] = _mm256_and_ps (b[0], c[0]); +}