From: Peter Bergner Date: Tue, 22 Aug 2017 20:08:51 +0000 (-0500) Subject: backport: re PR target/80210 (ICE in in extract_insn, at recog.c:2311 on ppc64 for... X-Git-Tag: releases/gcc-5.5.0~103 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=655b1fec3fcca98ea94bf12fdec80ee20b866002;p=thirdparty%2Fgcc.git backport: re PR target/80210 (ICE in in extract_insn, at recog.c:2311 on ppc64 for with __builtin_pow) gcc/ Backport from mainline 2017-08-17 Peter Bergner PR target/80210 * config/rs6000/rs6000.c (rs6000_activate_target_options): New function. (rs6000_set_current_function): Rewrite function to use it. gcc/testsuite/ Backport from mainline 2017-08-17 Peter Bergner PR target/80210 * gcc.target/powerpc/pr80210.c: New test. From-SVN: r251291 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bf7083329361..f1dcf48b372e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2017-08-22 Peter Bergner + + Backport from mainline + 2017-08-17 Peter Bergner + + PR target/80210 + * config/rs6000/rs6000.c (rs6000_activate_target_options): New function. + (rs6000_set_current_function): Rewrite function to use it. + 2017-08-22 Georg-Johann Lay Backport from 2017-07-26 gcc-7-branch r250562. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 142f02327fe0..32433b294a0d 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -32880,23 +32880,30 @@ rs6000_pragma_target_parse (tree args, tree pop_target) /* Remember the last target of rs6000_set_current_function. */ static GTY(()) tree rs6000_previous_fndecl; +/* Restore target's globals from NEW_TREE and invalidate the + rs6000_previous_fndecl cache. */ + +static void +rs6000_activate_target_options (tree new_tree) +{ + cl_target_option_restore (&global_options, TREE_TARGET_OPTION (new_tree)); + if (TREE_TARGET_GLOBALS (new_tree)) + restore_target_globals (TREE_TARGET_GLOBALS (new_tree)); + else if (new_tree == target_option_default_node) + restore_target_globals (&default_target_globals); + else + TREE_TARGET_GLOBALS (new_tree) = save_target_globals_default_opts (); + rs6000_previous_fndecl = NULL_TREE; +} + /* Establish appropriate back-end context for processing the function FNDECL. The argument might be NULL to indicate processing at top level, outside of any function scope. */ static void rs6000_set_current_function (tree fndecl) { - tree old_tree = (rs6000_previous_fndecl - ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl) - : NULL_TREE); - - tree new_tree = (fndecl - ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl) - : NULL_TREE); - if (TARGET_DEBUG_TARGET) { - bool print_final = false; fprintf (stderr, "\n==================== rs6000_set_current_function"); if (fndecl) @@ -32909,58 +32916,60 @@ rs6000_set_current_function (tree fndecl) fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl); fprintf (stderr, "\n"); + } + + /* Only change the context if the function changes. This hook is called + several times in the course of compiling a function, and we don't want to + slow things down too much or call target_reinit when it isn't safe. */ + if (fndecl == rs6000_previous_fndecl) + return; + + tree old_tree; + if (rs6000_previous_fndecl == NULL_TREE) + old_tree = target_option_current_node; + else if (DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl)) + old_tree = DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl); + else + old_tree = target_option_default_node; + + tree new_tree; + if (fndecl == NULL_TREE) + { + if (old_tree != target_option_current_node) + new_tree = target_option_current_node; + else + new_tree = NULL_TREE; + } + else + { + new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl); + if (new_tree == NULL_TREE) + new_tree = target_option_default_node; + } + + if (TARGET_DEBUG_TARGET) + { if (new_tree) { fprintf (stderr, "\nnew fndecl target specific options:\n"); debug_tree (new_tree); - print_final = true; } if (old_tree) { fprintf (stderr, "\nold fndecl target specific options:\n"); debug_tree (old_tree); - print_final = true; } - if (print_final) + if (old_tree != NULL_TREE || new_tree != NULL_TREE) fprintf (stderr, "--------------------\n"); } - /* Only change the context if the function changes. This hook is called - several times in the course of compiling a function, and we don't want to - slow things down too much or call target_reinit when it isn't safe. */ - if (fndecl && fndecl != rs6000_previous_fndecl) - { - rs6000_previous_fndecl = fndecl; - if (old_tree == new_tree) - ; - - else if (new_tree && new_tree != target_option_default_node) - { - cl_target_option_restore (&global_options, - TREE_TARGET_OPTION (new_tree)); - if (TREE_TARGET_GLOBALS (new_tree)) - restore_target_globals (TREE_TARGET_GLOBALS (new_tree)); - else - TREE_TARGET_GLOBALS (new_tree) - = save_target_globals_default_opts (); - } + if (new_tree && old_tree != new_tree) + rs6000_activate_target_options (new_tree); - else if (old_tree && old_tree != target_option_default_node) - { - new_tree = target_option_current_node; - cl_target_option_restore (&global_options, - TREE_TARGET_OPTION (new_tree)); - if (TREE_TARGET_GLOBALS (new_tree)) - restore_target_globals (TREE_TARGET_GLOBALS (new_tree)); - else if (new_tree == target_option_default_node) - restore_target_globals (&default_target_globals); - else - TREE_TARGET_GLOBALS (new_tree) - = save_target_globals_default_opts (); - } - } + if (fndecl) + rs6000_previous_fndecl = fndecl; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d437045a9373..840acd1768c8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2017-08-22 Peter Bergner + + Backport from mainline + 2017-08-17 Peter Bergner + + PR target/80210 + * gcc.target/powerpc/pr80210.c: New test. + 2017-08-22 Georg-Johann Lay Backport from trunk r247719. diff --git a/gcc/testsuite/gcc.target/powerpc/pr80210.c b/gcc/testsuite/gcc.target/powerpc/pr80210.c new file mode 100644 index 000000000000..9e2f2d9da498 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr80210.c @@ -0,0 +1,10 @@ +/* Test for ICE arising from GCC target pragma. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +double +foo (double a) +{ + return __builtin_sqrt (a); +} +#pragma GCC target "no-powerpc-gpopt"