From b1eb28d14049e19baf772e6052a3cc388e85bd51 Mon Sep 17 00:00:00 2001 From: Peter Bergner Date: Fri, 18 Aug 2017 18:41:41 -0500 Subject: [PATCH] re PR target/80210 (ICE in in extract_insn, at recog.c:2311 on ppc64 for with __builtin_pow) gcc/ PR target/80210 * config/rs6000/rs6000.c (rs6000_activate_target_options): New function. (rs6000_set_current_function): Rewrite function to use it. gcc/testsuite/ PR target/80210 * gcc.target/powerpc/pr80210.c: New test. From-SVN: r251190 --- gcc/ChangeLog | 6 ++ gcc/config/rs6000/rs6000.c | 99 ++++++++++++---------- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.target/powerpc/pr80210.c | 10 +++ 4 files changed, 75 insertions(+), 45 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/pr80210.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1fb9dab36d9..a632a4673cc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-08-18 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-18 H.J. Lu PR c/53037 diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index b31b1ab460f..5e694ffffe1 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -36664,23 +36664,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) @@ -36693,58 +36700,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 d21f64fcc0f..7fce23aaed1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-08-18 Peter Bergner + + PR target/80210 + * gcc.target/powerpc/pr80210.c: New test. + 2017-08-18 David Malcolm PR c++/81514 diff --git a/gcc/testsuite/gcc.target/powerpc/pr80210.c b/gcc/testsuite/gcc.target/powerpc/pr80210.c new file mode 100644 index 00000000000..9e2f2d9da49 --- /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" -- 2.30.2