From 6ca513f9b24dacf47db395f4dc41d11037810706 Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Fri, 27 Jan 2017 11:22:30 +0000 Subject: [PATCH] [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 --- gcc/ChangeLog | 7 ++++++ gcc/config/arm/arm.c | 31 ++++++++++---------------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/arm/pr79239.c | 15 +++++++++++++ 4 files changed, 39 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arm/pr79239.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 401037701ee..3ef51ca9e8a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-01-27 Richard Earnshaw + + 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 * doc/invoke.texi (-fprofile-arcs): Document profiling support diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 944445fc86a..6cae17872a4 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 85425e47d60..aaabdf3f197 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-01-27 Richard Earnshaw + + PR target/79239 + * gcc.target/arm/pr79239.c: New test. + 2017-01-27 Dominik Vogt * 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 00000000000..d1f1b28510a --- /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; +} -- 2.30.2