summaryrefslogtreecommitdiff
path: root/0019-fp-model-Enable-fp-model-on-kunpeng.patch
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2025-02-28 10:03:49 +0000
committerCoprDistGit <infra@openeuler.org>2025-02-28 10:03:49 +0000
commit73127104a245052cd5cf29cdaaca3e5c32c70348 (patch)
tree8e28b63e478c43c252f18b49836dff7313affe54 /0019-fp-model-Enable-fp-model-on-kunpeng.patch
parent49d3feaf4665cdb07576fc1a2382a4d82a612d35 (diff)
automatic import of gccopeneuler24.03_LTS_SP1
Diffstat (limited to '0019-fp-model-Enable-fp-model-on-kunpeng.patch')
-rw-r--r--0019-fp-model-Enable-fp-model-on-kunpeng.patch405
1 files changed, 405 insertions, 0 deletions
diff --git a/0019-fp-model-Enable-fp-model-on-kunpeng.patch b/0019-fp-model-Enable-fp-model-on-kunpeng.patch
new file mode 100644
index 0000000..46ea52c
--- /dev/null
+++ b/0019-fp-model-Enable-fp-model-on-kunpeng.patch
@@ -0,0 +1,405 @@
+From 8cdb316a3fe205a3089b9c17aec0442f4d5f75be Mon Sep 17 00:00:00 2001
+From: bule <bule1@huawei.com>
+Date: Sun, 27 Aug 2023 16:49:04 +0800
+Subject: [PATCH 19/22] [fp-model] Enable fp-model on kunpeng
+
+Enable fp-model options on kunpeng for precision control.
+---
+ gcc/common.opt | 26 +++++
+ gcc/config/aarch64/aarch64-linux.h | 3 +-
+ gcc/flag-types.h | 9 ++
+ gcc/fortran/options.cc | 8 ++
+ gcc/opts-common.cc | 146 ++++++++++++++++++++++++++++-
+ gcc/opts.cc | 68 ++++++++++++++
+ 6 files changed, 256 insertions(+), 4 deletions(-)
+
+diff --git a/gcc/common.opt b/gcc/common.opt
+index 8a0dafc52..f5eef8a45 100644
+--- a/gcc/common.opt
++++ b/gcc/common.opt
+@@ -1642,6 +1642,32 @@ ffp-int-builtin-inexact
+ Common Var(flag_fp_int_builtin_inexact) Init(1) Optimization
+ Allow built-in functions ceil, floor, round, trunc to raise \"inexact\" exceptions.
+
++fftz
++Common Var(flag_ftz) Optimization
++Control fpcr register for flush to zero.
++
++fp-model=
++Common Joined RejectNegative Enum(fp_model) Var(flag_fp_model) Init(FP_MODEL_NORMAL) Optimization
++-fp-model=[normal|fast|precise|except|strict] Perform floating-point precision control.
++
++Enum
++Name(fp_model) Type(enum fp_model) UnknownError(unknown floating point precision model %qs)
++
++EnumValue
++Enum(fp_model) String(normal) Value(FP_MODEL_NORMAL)
++
++EnumValue
++Enum(fp_model) String(fast) Value(FP_MODEL_FAST)
++
++EnumValue
++Enum(fp_model) String(precise) Value(FP_MODEL_PRECISE)
++
++EnumValue
++Enum(fp_model) String(except) Value(FP_MODEL_EXCEPT)
++
++EnumValue
++Enum(fp_model) String(strict) Value(FP_MODEL_STRICT)
++
+ ; Nonzero means don't put addresses of constant functions in registers.
+ ; Used for compiling the Unix kernel, where strange substitutions are
+ ; done on the assembly output.
+diff --git a/gcc/config/aarch64/aarch64-linux.h b/gcc/config/aarch64/aarch64-linux.h
+index 5e4553d79..a5cba6391 100644
+--- a/gcc/config/aarch64/aarch64-linux.h
++++ b/gcc/config/aarch64/aarch64-linux.h
+@@ -50,7 +50,8 @@
+ #define LINK_SPEC LINUX_TARGET_LINK_SPEC AARCH64_ERRATA_LINK_SPEC
+
+ #define GNU_USER_TARGET_MATHFILE_SPEC \
+- "%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s}"
++ "%{Ofast|ffast-math|funsafe-math-optimizations|fp-model=fast|fftz:\
++ %{!fno-ftz:crtfastmath.o%s}}"
+
+ #undef ENDFILE_SPEC
+ #define ENDFILE_SPEC \
+diff --git a/gcc/flag-types.h b/gcc/flag-types.h
+index 2c8498169..64c64eb32 100644
+--- a/gcc/flag-types.h
++++ b/gcc/flag-types.h
+@@ -260,6 +260,15 @@ enum fp_contract_mode {
+ FP_CONTRACT_FAST = 2
+ };
+
++/* Floating-point precision mode. */
++enum fp_model {
++ FP_MODEL_NORMAL = 0,
++ FP_MODEL_FAST = 1,
++ FP_MODEL_PRECISE = 2,
++ FP_MODEL_EXCEPT = 3,
++ FP_MODEL_STRICT = 4
++};
++
+ /* Scalar storage order kind. */
+ enum scalar_storage_order_kind {
+ SSO_NATIVE = 0,
+diff --git a/gcc/fortran/options.cc b/gcc/fortran/options.cc
+index d0fa634f1..3eb99a84a 100644
+--- a/gcc/fortran/options.cc
++++ b/gcc/fortran/options.cc
+@@ -243,6 +243,7 @@ form_from_filename (const char *filename)
+ return f_form;
+ }
+
++static void gfc_handle_fpe_option (const char *arg, bool trap);
+
+ /* Finalize commandline options. */
+
+@@ -286,6 +287,13 @@ gfc_post_options (const char **pfilename)
+ if (flag_protect_parens == -1)
+ flag_protect_parens = !optimize_fast;
+
++ /* If fp-model=precise/strict, turn on all ffpe-trap and ffpe-summary. */
++ if (flag_fp_model == FP_MODEL_EXCEPT || flag_fp_model == FP_MODEL_STRICT)
++ {
++ gfc_handle_fpe_option ("all", false);
++ gfc_handle_fpe_option ("invalid,zero,overflow,underflow", true);
++ }
++
+ /* -Ofast sets implies -fstack-arrays unless an explicit size is set for
+ stack arrays. */
+ if (flag_stack_arrays == -1 && flag_max_stack_var_size == -2)
+diff --git a/gcc/opts-common.cc b/gcc/opts-common.cc
+index 7c07d5046..489a6e02a 100644
+--- a/gcc/opts-common.cc
++++ b/gcc/opts-common.cc
+@@ -28,7 +28,8 @@ along with GCC; see the file COPYING3. If not see
+ #include "spellcheck.h"
+ #include "opts-jobserver.h"
+
+-static void prune_options (struct cl_decoded_option **, unsigned int *);
++static void prune_options (struct cl_decoded_option **, unsigned int *,
++ unsigned int);
+
+ /* An option that is undocumented, that takes a joined argument, and
+ that doesn't fit any of the classes of uses (language/common,
+@@ -1091,7 +1092,7 @@ decode_cmdline_options_to_array (unsigned int argc, const char **argv,
+
+ *decoded_options = opt_array;
+ *decoded_options_count = num_decoded_options;
+- prune_options (decoded_options, decoded_options_count);
++ prune_options (decoded_options, decoded_options_count, lang_mask);
+ }
+
+ /* Return true if NEXT_OPT_IDX cancels OPT_IDX. Return false if the
+@@ -1112,11 +1113,109 @@ cancel_option (int opt_idx, int next_opt_idx, int orig_next_opt_idx)
+ return false;
+ }
+
++/* Check whether opt_idx exists in decoded_options array between index
++ start and end. If found, return its index in decoded_options,
++ else return end. */
++static unsigned int
++find_opt_idx (const struct cl_decoded_option *decoded_options,
++ unsigned int decoded_options_count,
++ unsigned int start, unsigned int end, unsigned int opt_idx)
++{
++ gcc_assert (end <= decoded_options_count);
++ gcc_assert (opt_idx < cl_options_count);
++ unsigned int k;
++ for (k = start; k < end; k++)
++ {
++ if (decoded_options[k].opt_index == opt_idx)
++ {
++ return k;
++ }
++ }
++ return k;
++}
++
++/* remove the opt_index element from decoded_options array. */
++static unsigned int
++remove_option (struct cl_decoded_option *decoded_options,
++ unsigned int decoded_options_count,
++ unsigned int opt_index)
++{
++ gcc_assert (opt_index < decoded_options_count);
++ unsigned int i;
++ for (i = opt_index; i < decoded_options_count - 1; i++)
++ {
++ decoded_options[i] = decoded_options[i + 1];
++ }
++ return decoded_options_count - 1;
++}
++
++/* Handle the priority between fp-model, Ofast, and
++ ffast-math. */
++static unsigned int
++handle_fp_model_driver (struct cl_decoded_option *decoded_options,
++ unsigned int decoded_options_count,
++ unsigned int fp_model_index,
++ unsigned int lang_mask)
++{
++ struct cl_decoded_option fp_model_opt = decoded_options[fp_model_index];
++ enum fp_model model = (enum fp_model) fp_model_opt.value;
++ if (model == FP_MODEL_PRECISE || model == FP_MODEL_STRICT)
++ {
++ /* If found Ofast, override Ofast with O3. */
++ unsigned int Ofast_index;
++ Ofast_index = find_opt_idx (decoded_options, decoded_options_count,
++ 0, decoded_options_count, OPT_Ofast);
++ while (Ofast_index != decoded_options_count)
++ {
++ const char *tmp_argv = "-O3";
++ decode_cmdline_option (&tmp_argv, lang_mask,
++ &decoded_options[Ofast_index]);
++ warning (0, "%<-Ofast%> is degraded to %<-O3%> due to %qs",
++ fp_model_opt.orig_option_with_args_text);
++ Ofast_index = find_opt_idx (decoded_options, decoded_options_count,
++ 0, decoded_options_count, OPT_Ofast);
++ }
++ /* If found ffast-math before fp-model=precise/strict
++ it, cancel it. */
++ unsigned int ffast_math_index;
++ ffast_math_index
++ = find_opt_idx (decoded_options, decoded_options_count, 0,
++ fp_model_index, OPT_ffast_math);
++ if (ffast_math_index != fp_model_index)
++ {
++ decoded_options_count
++ = remove_option (decoded_options, decoded_options_count,
++ ffast_math_index);
++ warning (0, "%<-ffast-math%> before %qs is canceled",
++ fp_model_opt.orig_option_with_args_text);
++ }
++ }
++ if (model == FP_MODEL_FAST)
++ {
++ /* If found -fno-fast-math after fp-model=fast, cancel this one. */
++ unsigned int fno_fast_math_index;
++ fno_fast_math_index
++ = find_opt_idx (decoded_options, decoded_options_count, fp_model_index,
++ decoded_options_count, OPT_ffast_math);
++ if (fno_fast_math_index != decoded_options_count
++ && decoded_options[fno_fast_math_index].value == 0)
++ {
++ decoded_options_count
++ = remove_option (decoded_options, decoded_options_count,
++ fp_model_index);
++ warning (0,
++ "%<-fp-model=fast%> before %<-fno-fast-math%> is canceled");
++ }
++ }
++ return decoded_options_count;
++}
++
+ /* Filter out options canceled by the ones after them. */
+
+ static void
+ prune_options (struct cl_decoded_option **decoded_options,
+- unsigned int *decoded_options_count)
++ unsigned int *decoded_options_count,
++ unsigned int lang_mask)
+ {
+ unsigned int old_decoded_options_count = *decoded_options_count;
+ struct cl_decoded_option *old_decoded_options = *decoded_options;
+@@ -1127,7 +1226,12 @@ prune_options (struct cl_decoded_option **decoded_options,
+ const struct cl_option *option;
+ unsigned int fdiagnostics_color_idx = 0;
+
++ if (!diagnostic_ready_p ())
++ diagnostic_initialize (global_dc, 0);
++
+ /* Remove arguments which are negated by others after them. */
++
++ unsigned int fp_model_index = old_decoded_options_count;
+ new_decoded_options_count = 0;
+ for (i = 0; i < old_decoded_options_count; i++)
+ {
+@@ -1151,6 +1255,34 @@ prune_options (struct cl_decoded_option **decoded_options,
+ fdiagnostics_color_idx = i;
+ continue;
+
++ case OPT_fp_model_:
++ /* Only the last fp-model option will take effect. */
++ unsigned int next_fp_model_idx;
++ next_fp_model_idx = find_opt_idx (old_decoded_options,
++ old_decoded_options_count,
++ i + 1,
++ old_decoded_options_count,
++ OPT_fp_model_);
++ if (next_fp_model_idx != old_decoded_options_count)
++ {
++ /* Found more than one fp-model, cancel this one. */
++ if (old_decoded_options[i].value
++ != old_decoded_options[next_fp_model_idx].value)
++ {
++ warning (0, "%qs is overrided by %qs",
++ old_decoded_options[i].
++ orig_option_with_args_text,
++ old_decoded_options[next_fp_model_idx].
++ orig_option_with_args_text);
++ }
++ break;
++ }
++ else
++ {
++ /* Found the last fp-model option. */
++ fp_model_index = new_decoded_options_count;
++ }
++ /* FALLTHRU. */
+ default:
+ gcc_assert (opt_idx < cl_options_count);
+ option = &cl_options[opt_idx];
+@@ -1190,6 +1322,14 @@ keep:
+ break;
+ }
+ }
++ if (fp_model_index < new_decoded_options_count)
++ {
++ new_decoded_options_count
++ = handle_fp_model_driver (new_decoded_options,
++ new_decoded_options_count,
++ fp_model_index,
++ lang_mask);
++ }
+
+ if (fdiagnostics_color_idx >= 1)
+ {
+diff --git a/gcc/opts.cc b/gcc/opts.cc
+index a97630d1c..b522ed7e2 100644
+--- a/gcc/opts.cc
++++ b/gcc/opts.cc
+@@ -328,6 +328,7 @@ static void set_debug_level (uint32_t dinfo, int extended,
+ struct gcc_options *opts_set,
+ location_t loc);
+ static void set_fast_math_flags (struct gcc_options *opts, int set);
++static void set_fp_model_flags (struct gcc_options *opts, int set);
+ static void decode_d_option (const char *arg, struct gcc_options *opts,
+ location_t loc, diagnostic_context *dc);
+ static void set_unsafe_math_optimizations_flags (struct gcc_options *opts,
+@@ -2857,6 +2858,10 @@ common_handle_option (struct gcc_options *opts,
+ set_fast_math_flags (opts, value);
+ break;
+
++ case OPT_fp_model_:
++ set_fp_model_flags (opts, value);
++ break;
++
+ case OPT_funsafe_math_optimizations:
+ set_unsafe_math_optimizations_flags (opts, value);
+ break;
+@@ -3266,6 +3271,69 @@ set_fast_math_flags (struct gcc_options *opts, int set)
+ }
+ }
+
++/* Handle fp-model options. */
++static void
++set_fp_model_flags (struct gcc_options *opts, int set)
++{
++ enum fp_model model = (enum fp_model) set;
++ switch (model)
++ {
++ case FP_MODEL_FAST:
++ /* Equivalent to open ffast-math. */
++ set_fast_math_flags (opts, 1);
++ break;
++
++ case FP_MODEL_PRECISE:
++ /* Equivalent to close ffast-math. */
++ set_fast_math_flags (opts, 0);
++ /* Turn on -frounding-math -fsignaling-nans. */
++ if (!opts->frontend_set_flag_signaling_nans)
++ opts->x_flag_signaling_nans = 1;
++ if (!opts->frontend_set_flag_rounding_math)
++ opts->x_flag_rounding_math = 1;
++ opts->x_flag_expensive_optimizations = 0;
++ opts->x_flag_code_hoisting = 0;
++ opts->x_flag_predictive_commoning = 0;
++ opts->x_flag_fp_contract_mode = FP_CONTRACT_OFF;
++ break;
++
++ case FP_MODEL_EXCEPT:
++ if (!opts->frontend_set_flag_signaling_nans)
++ opts->x_flag_signaling_nans = 1;
++ if (!opts->frontend_set_flag_errno_math)
++ opts->x_flag_errno_math = 1;
++ if (!opts->frontend_set_flag_trapping_math)
++ opts->x_flag_trapping_math = 1;
++ opts->x_flag_fp_int_builtin_inexact = 1;
++ /* Also turn on ffpe-trap in fortran. */
++ break;
++
++ case FP_MODEL_STRICT:
++ /* Turn on both precise and except. */
++ if (!opts->frontend_set_flag_signaling_nans)
++ opts->x_flag_signaling_nans = 1;
++ if (!opts->frontend_set_flag_rounding_math)
++ opts->x_flag_rounding_math = 1;
++ opts->x_flag_expensive_optimizations = 0;
++ opts->x_flag_code_hoisting = 0;
++ opts->x_flag_predictive_commoning = 0;
++ if (!opts->frontend_set_flag_errno_math)
++ opts->x_flag_errno_math = 1;
++ if (!opts->frontend_set_flag_trapping_math)
++ opts->x_flag_trapping_math = 1;
++ opts->x_flag_fp_int_builtin_inexact = 1;
++ opts->x_flag_fp_contract_mode = FP_CONTRACT_OFF;
++ break;
++
++ case FP_MODEL_NORMAL:
++ /* Do nothing. */
++ break;
++
++ default:
++ gcc_unreachable ();
++ }
++}
++
+ /* When -funsafe-math-optimizations is set the following
+ flags are set as well. */
+ static void
+--
+2.33.0
+