diff options
author | Richard Earnshaw <rearnsha@arm.com> | 2017-01-27 11:22:30 +0000 |
---|---|---|
committer | Ramana Radhakrishnan <ramana@gcc.gnu.org> | 2017-01-27 11:22:30 +0000 |
commit | 6ca513f9b24dacf47db395f4dc41d11037810706 (patch) | |
tree | 1fd60ff0eee31a4f0c215b265fb2431ef590d8c3 | |
parent | c7181f1393788572fa451bfd8d45d62c8889dd50 (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 31 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/pr79239.c | 15 |
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; +} |