[ARM] Fix PR target/79239 - unrecognized insn after pragma gcc pop_options
authorRichard Earnshaw <rearnsha@arm.com>
Fri, 27 Jan 2017 11:22:30 +0000 (11:22 +0000)
committerRamana Radhakrishnan <ramana@gcc.gnu.org>
Fri, 27 Jan 2017 11:22:30 +0000 (11:22 +0000)
{committed for rearnsha}

It turns out that because the compiler uses a hash table to save the
cl_target_option structures it is unsafe to modify the result of
build_target_option_node() (doing so will cause the hash lookup to
fail).  This PR was due to not properly understanding this limitation.

The fix is to create temporary copies of the cl_target_option nodes for
use during target option processing and then only creating the tree node
once the options have been suitably modified.

gcc:
        PR target/79239
        * arm.c (arm_option_override): Don't call build_target_option_node
        until after doing all option overrides.
        (arm_valid_target_attribute_tree): Likewise.

gcc/testsuite:
        * gcc.target/arm/pr79239.c: New test.

From-SVN: r244965

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/pr79239.c [new file with mode: 0644]

index 401037701ee563b2a2f720f850103317b9f2bde2..3ef51ca9e8a8514b0b77d5612409203d4a8ae7ac 100644 (file)
@@ -1,3 +1,10 @@
+2017-01-27  Richard Earnshaw  <rearnsha@arm.com>
+
+       PR target/79239
+        * arm.c (arm_option_override): Don't call build_target_option_node
+        until after doing all option overrides.
+        (arm_valid_target_attribute_tree): Likewise.
+
 2017-01-27  Martin Liska  <mliska@suse.cz>
 
        * doc/invoke.texi (-fprofile-arcs): Document profiling support
index 944445fc86ae848b36c8a90db4b3760476c8b467..6cae17872a4d87fd836b08b6533e089f32a652fb 100644 (file)
@@ -3256,6 +3256,7 @@ arm_option_override (void)
 {
   static const enum isa_feature fpu_bitlist[] = { ISA_ALL_FPU, isa_nobit };
   static const enum isa_feature quirk_bitlist[] = { ISA_ALL_QUIRKS, isa_nobit};
+  cl_target_option opts;
 
   isa_quirkbits = sbitmap_alloc (isa_num_bits);
   arm_initialize_isa (isa_quirkbits, quirk_bitlist);
@@ -3283,14 +3284,9 @@ arm_option_override (void)
       arm_fpu_index = (enum fpu_type) fpu_index;
     }
 
-  /* Create the default target_options structure.  We need this early
-     to configure the overall build target.  */
-  target_option_default_node = target_option_current_node
-    = build_target_option_node (&global_options);
-
-  arm_configure_build_target (&arm_active_target,
-                             TREE_TARGET_OPTION (target_option_default_node),
-                             &global_options_set, true);
+  cl_target_option_save (&opts, &global_options);
+  arm_configure_build_target (&arm_active_target, &opts, &global_options_set,
+                             true);
 
 #ifdef SUBTARGET_OVERRIDE_OPTIONS
   SUBTARGET_OVERRIDE_OPTIONS;
@@ -3646,9 +3642,10 @@ arm_option_override (void)
   arm_option_check_internal (&global_options);
   arm_option_params_internal ();
 
-  /* Resynchronize the saved target options.  */
-  cl_target_option_save (TREE_TARGET_OPTION (target_option_default_node),
-                        &global_options);
+  /* Create the default target_options structure.  */
+  target_option_default_node = target_option_current_node
+    = build_target_option_node (&global_options);
+
   /* Register global variables with the garbage collector.  */
   arm_add_gc_roots ();
 
@@ -30347,22 +30344,18 @@ tree
 arm_valid_target_attribute_tree (tree args, struct gcc_options *opts,
                                 struct gcc_options *opts_set)
 {
-  tree t;
+  struct cl_target_option cl_opts;
 
   if (!arm_valid_target_attribute_rec (args, opts))
     return NULL_TREE;
 
-  t = build_target_option_node (opts);
-  arm_configure_build_target (&arm_active_target, TREE_TARGET_OPTION (t),
-                             opts_set, false);
+  cl_target_option_save (&cl_opts, opts);
+  arm_configure_build_target (&arm_active_target, &cl_opts, opts_set, false);
   arm_option_check_internal (opts);
   /* Do any overrides, such as global options arch=xxx.  */
   arm_option_override_internal (opts, opts_set);
 
-  /* Resynchronize the saved target options.  */
-  cl_target_option_save (TREE_TARGET_OPTION (t), opts);
-
-  return t;
+  return build_target_option_node (opts);
 }
 
 static void 
index 85425e47d60b8912b0d1476a8963a36b6feb5028..aaabdf3f197c2ec3679e69cca5ba43d96500c241 100644 (file)
@@ -1,3 +1,8 @@
+2017-01-27  Richard Earnshaw  <rearnsha@arm.com>
+
+       PR target/79239
+       * gcc.target/arm/pr79239.c: New test.
+
 2017-01-27  Dominik Vogt  <vogt@linux.vnet.ibm.com>
 
        * gcc.target/s390/md/setmem_long-1.c: Remove xfail, skip with -O0.
diff --git a/gcc/testsuite/gcc.target/arm/pr79239.c b/gcc/testsuite/gcc.target/arm/pr79239.c
new file mode 100644 (file)
index 0000000..d1f1b28
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_fp_ok }  */
+/* { dg-add-options arm_fp } */
+
+#pragma GCC push_options
+#pragma GCC target "fpu=crypto-neon-fp-armv8"
+int a, b;
+extern __inline __attribute__((__gnu_inline__)) int fn1() {}
+
+#pragma GCC pop_options
+void
+fn2() {
+  if (b * 0.77 + 0.5)
+    a = 0;
+}