https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69245
--- Comment #6 from chrbr at gcc dot gnu.org --- (In reply to ktkachov from comment #5) > The problem is we never end up setting TREE_TARGET_GLOBALS for fn2. > From what I can gather that's TARGET_SET_CURRENT_FUNCTION's job (although > the documentation for these things is scarce :( ) > > When we call arm_set_current_function for fn2 the old_tree is NULL because > arm_pragma_target_parse will have reset arm_previous_fndecl when popping the > target pragma. > > new_tree will also be NULL because DECL_FUNCTION_SPECIFIC_TARGET for fndecl > is only supposed to be set in the target attribute parsing code, but not the > pragma parsing code (again, documentation here is scarce). > > So we end up bypassing all the content in arm_set_current_function and not > setting TREE_TARGET_GLOBALS which means the midend doesn't try to reset the > optabs for fn2. > > x86 gets away with this because ix86_reset_previous_fndecl besides clearing > the previous fndecl cache also sets TREE_TARGET_GLOBALS for > target_option_current_node. > > rs6000 seems to never reset its previous fndecl (rs6000_previous_fndecl) so > its version old_tree will always point to some tree (AFAICT). > > Ugh. So for arm my thoughts are we should not exit early on the old_tree == > new_tree condition if both trees are NULL but rather follow the second arm > of the if statement in arm_set_current_function where we set new_tree to > target_option_current_code. > > Hacking a prototype for that idea fixes the testcase for me. > Christian, what do you think? arm_reset_current_function assumes indeed that all the state switches are done, so it would be more consistent to call restore_target_globals in pragma_target_parse as well instead of splitting the work in 2 different places. Maybe factorizing the common code from both ?