re PR target/80210 (ICE in in extract_insn, at recog.c:2311 on ppc64 for with __built...
authorPeter Bergner <bergner@vnet.ibm.com>
Fri, 18 Aug 2017 23:41:41 +0000 (18:41 -0500)
committerPeter Bergner <bergner@gcc.gnu.org>
Fri, 18 Aug 2017 23:41:41 +0000 (18:41 -0500)
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
gcc/config/rs6000/rs6000.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/pr80210.c [new file with mode: 0644]

index 1fb9dab36d9e4d7ff3cc86cfb8be986a166bf2ef..a632a4673ccf1b5093300f3f62843a0e3c448a59 100644 (file)
@@ -1,3 +1,9 @@
+2017-08-18  Peter Bergner  <bergner@vnet.ibm.com>
+
+       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  <hongjiu.lu@intel.com>
 
        PR c/53037
index b31b1ab460fa898ee0e2db724ae3527159bc1cbb..5e694ffffe1dd45689f59f97fdf73feafec8c2ff 100644 (file)
@@ -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;
 }
 
 \f
index d21f64fcc0f61cd122ce6bbea84eadbd04675792..7fce23aaed17ad39d07f349059c5ef73034820a5 100644 (file)
@@ -1,3 +1,8 @@
+2017-08-18  Peter Bergner  <bergner@vnet.ibm.com>
+
+       PR target/80210
+       * gcc.target/powerpc/pr80210.c: New test.
+
 2017-08-18  David Malcolm  <dmalcolm@redhat.com>
 
        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 (file)
index 0000000..9e2f2d9
--- /dev/null
@@ -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"