diff options
Diffstat (limited to 'gcc/config/i386/i386-options.c')
-rw-r--r-- | gcc/config/i386/i386-options.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/gcc/config/i386/i386-options.c b/gcc/config/i386/i386-options.c index 40714c8..70b5f09 100644 --- a/gcc/config/i386/i386-options.c +++ b/gcc/config/i386/i386-options.c @@ -1374,6 +1374,14 @@ ix86_valid_target_attribute_tree (tree fndecl, tree args, /* Add any builtin functions with the new isa if any. */ ix86_add_new_builtins (opts->x_ix86_isa_flags, opts->x_ix86_isa_flags2); + enum excess_precision orig_ix86_excess_precision + = opts->x_ix86_excess_precision; + bool orig_ix86_unsafe_math_optimizations + = opts->x_ix86_unsafe_math_optimizations; + opts->x_ix86_excess_precision = opts->x_flag_excess_precision; + opts->x_ix86_unsafe_math_optimizations + = opts->x_flag_unsafe_math_optimizations; + /* Save the current options unless we are validating options for #pragma. */ t = build_target_option_node (opts, opts_set); @@ -1382,6 +1390,9 @@ ix86_valid_target_attribute_tree (tree fndecl, tree args, opts->x_ix86_tune_string = orig_tune_string; opts_set->x_ix86_fpmath = orig_fpmath_set; opts_set->x_prefer_vector_width_type = orig_pvw_set; + opts->x_ix86_excess_precision = orig_ix86_excess_precision; + opts->x_ix86_unsafe_math_optimizations + = orig_ix86_unsafe_math_optimizations; release_options_strings (option_strings); } @@ -3019,8 +3030,14 @@ ix86_option_override_internal (bool main_args_p, /* Save the initial options in case the user does function specific options. */ if (main_args_p) - target_option_default_node = target_option_current_node - = build_target_option_node (opts, opts_set); + { + opts->x_ix86_excess_precision + = opts->x_flag_excess_precision; + opts->x_ix86_unsafe_math_optimizations + = opts->x_flag_unsafe_math_optimizations; + target_option_default_node = target_option_current_node + = build_target_option_node (opts, opts_set); + } if (opts->x_flag_cf_protection != CF_NONE) opts->x_flag_cf_protection @@ -3326,6 +3343,24 @@ ix86_set_current_function (tree fndecl) else TREE_TARGET_GLOBALS (new_tree) = save_target_globals_default_opts (); } + else if (flag_unsafe_math_optimizations + != TREE_TARGET_OPTION (new_tree)->x_ix86_unsafe_math_optimizations + || (flag_excess_precision + != TREE_TARGET_OPTION (new_tree)->x_ix86_excess_precision)) + { + cl_target_option_restore (&global_options, &global_options_set, + TREE_TARGET_OPTION (new_tree)); + ix86_excess_precision = flag_excess_precision; + ix86_unsafe_math_optimizations = flag_unsafe_math_optimizations; + DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_tree + = build_target_option_node (&global_options, &global_options_set); + 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 (); + } ix86_previous_fndecl = fndecl; static bool prev_no_caller_saved_registers; |