aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2017-01-27 11:22:30 +0000
committerRamana Radhakrishnan <ramana@gcc.gnu.org>2017-01-27 11:22:30 +0000
commit6ca513f9b24dacf47db395f4dc41d11037810706 (patch)
tree1fd60ff0eee31a4f0c215b265fb2431ef590d8c3
parentc7181f1393788572fa451bfd8d45d62c8889dd50 (diff)
downloadgcc-6ca513f9b24dacf47db395f4dc41d11037810706.zip
gcc-6ca513f9b24dacf47db395f4dc41d11037810706.tar.gz
gcc-6ca513f9b24dacf47db395f4dc41d11037810706.tar.bz2
[ARM] Fix PR target/79239 - unrecognized insn after pragma gcc pop_options
{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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/arm/arm.c31
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/arm/pr79239.c15
4 files changed, 39 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4010377..3ef51ca 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 944445f..6cae178 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 85425e4..aaabdf3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..d1f1b28
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr79239.c
@@ -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;
+}