On 9/6/21 14:16, Richard Biener wrote:
On Mon, Sep 6, 2021 at 1:46 PM Jakub Jelinek <ja...@redhat.com> wrote:
On Mon, Sep 06, 2021 at 01:37:46PM +0200, Martin Liška wrote:
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1323,6 +1323,14 @@ finish_options (struct gcc_options *opts, struct
gcc_options *opts_set,
= (opts->x_flag_unroll_loops
|| opts->x_flag_peel_loops
|| opts->x_optimize >= 3);
+
+ /* With -fcx-limited-range, we do cheap and quick complex arithmetic. */
+ if (opts->x_flag_cx_limited_range)
+ flag_complex_method = 0;
+
+ /* With -fcx-fortran-rules, we do something in-between cheap and C99. */
+ if (opts->x_flag_cx_fortran_rules)
+ flag_complex_method = 1;
That should then be opts->x_flag_complex_method instead of flag_complex_method.
Ok with that change.
But the C/C++ langhooks also set flag_complex_method so I fail to see how
this helps? As said I was referring to -fcx-limited-range on the command-line
and -fno-cx-limited-range in the optimize node to undo this which should
get you the langhook setting of flag_complex_method = 2.
You are right, it's even more complicated as -fno-cx-limited-range is target
specific.
Option handling has been introducing surprises every time ...
The following tested patch should handle it.
Ready to be installed?
Thanks,
Martin
Note, I think we want to do much more in finish_options and less in
process_options, anything that is about Optimization options rather than
just the global ones. Though one needs to be careful with the cases where
the code diagnoses something.
Jakub
From e88ae14be7c5609a969897b5d09f40709fea8a34 Mon Sep 17 00:00:00 2001
From: Martin Liska <mli...@suse.cz>
Date: Fri, 3 Sep 2021 10:53:00 +0200
Subject: [PATCH] flag_complex_method: support optimize attribute
gcc/c-family/ChangeLog:
* c-opts.c (c_common_init_options_struct): Set also
x_flag_default_complex_method.
gcc/ChangeLog:
* common.opt: Add new variable flag_default_complex_method.
* opts.c (finish_options): Handle flags related to
x_flag_complex_method.
* toplev.c (process_options): Remove option handling related
to flag_complex_method.
gcc/go/ChangeLog:
* go-lang.c (go_langhook_init_options_struct): Set also
x_flag_default_complex_method.
gcc/lto/ChangeLog:
* lto-lang.c (lto_init_options_struct): Set also
x_flag_default_complex_method.
gcc/testsuite/ChangeLog:
* gcc.c-torture/compile/attr-complex-method-2.c: New test.
* gcc.c-torture/compile/attr-complex-method.c: New test.
---
gcc/c-family/c-opts.c | 1 +
gcc/common.opt | 3 +++
gcc/go/go-lang.c | 1 +
gcc/lto/lto-lang.c | 1 +
gcc/opts.c | 12 ++++++++++++
.../gcc.c-torture/compile/attr-complex-method-2.c | 10 ++++++++++
.../gcc.c-torture/compile/attr-complex-method.c | 10 ++++++++++
gcc/toplev.c | 8 --------
8 files changed, 38 insertions(+), 8 deletions(-)
create mode 100644 gcc/testsuite/gcc.c-torture/compile/attr-complex-method-2.c
create mode 100644 gcc/testsuite/gcc.c-torture/compile/attr-complex-method.c
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index fdde082158b..3eaab5e1530 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -222,6 +222,7 @@ c_common_init_options_struct (struct gcc_options *opts)
/* By default, C99-like requirements for complex multiply and divide. */
opts->x_flag_complex_method = 2;
+ opts->x_flag_default_complex_method = opts->x_flag_complex_method;
}
/* Common initialization before calling option handlers. */
diff --git a/gcc/common.opt b/gcc/common.opt
index 7d69ab5ef7c..6bfe0b74023 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -59,6 +59,9 @@ enum incremental_link flag_incremental_link = INCREMENTAL_LINK_NONE
Variable
int flag_complex_method = 1
+Variable
+int flag_default_complex_method = 1
+
; Language specific warning pass for unused results.
Variable
bool flag_warn_unused_result = false
diff --git a/gcc/go/go-lang.c b/gcc/go/go-lang.c
index a01db8dbdcd..c3ae6f012bb 100644
--- a/gcc/go/go-lang.c
+++ b/gcc/go/go-lang.c
@@ -174,6 +174,7 @@ go_langhook_init_options_struct (struct gcc_options *opts)
/* Default to avoiding range issues for complex multiply and
divide. */
opts->x_flag_complex_method = 2;
+ opts->x_flag_default_complex_method = opts->x_flag_complex_method;
/* The builtin math functions should not set errno. */
opts->x_flag_errno_math = 0;
diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
index 92f499643b5..a014e5884e0 100644
--- a/gcc/lto/lto-lang.c
+++ b/gcc/lto/lto-lang.c
@@ -813,6 +813,7 @@ lto_init_options_struct (struct gcc_options *opts)
safe choice. This will pessimize Fortran code with LTO unless
people specify a complex method manually or use -ffast-math. */
opts->x_flag_complex_method = 2;
+ opts->x_flag_default_complex_method = opts->x_flag_complex_method;
}
/* Handle command-line option SCODE. If the option takes an argument, it is
diff --git a/gcc/opts.c b/gcc/opts.c
index e0501551ef5..8cf868ac88d 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1323,6 +1323,18 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
= (opts->x_flag_unroll_loops
|| opts->x_flag_peel_loops
|| opts->x_optimize >= 3);
+
+ /* With -fcx-limited-range, we do cheap and quick complex arithmetic. */
+ if (opts->x_flag_cx_limited_range)
+ opts->x_flag_complex_method = 0;
+ else if (opts_set->x_flag_cx_limited_range)
+ opts->x_flag_complex_method = opts->x_flag_default_complex_method;
+
+ /* With -fcx-fortran-rules, we do something in-between cheap and C99. */
+ if (opts->x_flag_cx_fortran_rules)
+ opts->x_flag_complex_method = 1;
+ else if (opts_set->x_flag_cx_fortran_rules)
+ opts->x_flag_complex_method = opts->x_flag_default_complex_method;
}
#define LEFT_COLUMN 27
diff --git a/gcc/testsuite/gcc.c-torture/compile/attr-complex-method-2.c b/gcc/testsuite/gcc.c-torture/compile/attr-complex-method-2.c
new file mode 100644
index 00000000000..a3dc9c1ba91
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/attr-complex-method-2.c
@@ -0,0 +1,10 @@
+/* { dg-additional-options "-fcx-limited-range -fdump-tree-optimized" } */
+
+#pragma GCC optimize "-fno-cx-limited-range"
+
+void do_div (_Complex double *a, _Complex double *b)
+{
+ *a = *b / (4.0 - 5.0fi);
+}
+
+/* { dg-final { scan-tree-dump "__divdc3" "optimized" } } */
diff --git a/gcc/testsuite/gcc.c-torture/compile/attr-complex-method.c b/gcc/testsuite/gcc.c-torture/compile/attr-complex-method.c
new file mode 100644
index 00000000000..f08b72e273f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/attr-complex-method.c
@@ -0,0 +1,10 @@
+/* { dg-additional-options "-fdump-tree-optimized" } */
+
+#pragma GCC optimize "-fcx-limited-range"
+
+void do_div (_Complex double *a, _Complex double *b)
+{
+ *a = *b / (4.0 - 5.0fi);
+}
+
+/* { dg-final { scan-tree-dump-not "__divdc3" "optimized" } } */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 14d1335e79e..e1688aae724 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1695,14 +1695,6 @@ process_options (void)
flag_stack_check = NO_STACK_CHECK;
}
- /* With -fcx-limited-range, we do cheap and quick complex arithmetic. */
- if (flag_cx_limited_range)
- flag_complex_method = 0;
-
- /* With -fcx-fortran-rules, we do something in-between cheap and C99. */
- if (flag_cx_fortran_rules)
- flag_complex_method = 1;
-
/* Targets must be able to place spill slots at lower addresses. If the
target already uses a soft frame pointer, the transition is trivial. */
if (!FRAME_GROWS_DOWNWARD && flag_stack_protect)
--
2.33.0