Variable
enum incremental_link flag_incremental_link = INCREMENTAL_LINK_NONE
-; 0 means straightforward implementation of complex divide acceptable.
-; 1 means wide ranges of inputs must work for complex divide.
-; 2 means C99-like requirements for complex multiply and divide.
-Variable
-int flag_complex_method = 1
-
Variable
int flag_default_complex_method = 1
Common Ignore
Does nothing. Preserved for backward compatibility.
+fcx-method=
+Common Joined RejectNegative Enum(complex_method) Var(flag_complex_method) Optimization SetByCombined
+
+Enum
+Name(complex_method) Type(int)
+
+; straightforward implementation of complex divide acceptable.
+EnumValue
+Enum(complex_method) String(limited-range) Value(0)
+
+; wide ranges of inputs must work for complex divide.
+EnumValue
+Enum(complex_method) String(fortran) Value(1)
+
+; C99-like requirements for complex multiply and divide.
+EnumValue
+Enum(complex_method) String(stdc) Value(2)
+
fcx-limited-range
-Common Var(flag_cx_limited_range) Optimization SetByCombined
+Common Alias(fcx-method=,limited-range,stdc)
Omit range reduction step when performing complex division.
fcx-fortran-rules
-Common Var(flag_cx_fortran_rules) Optimization
+Common Alias(fcx-method=,fortran,stdc)
Complex multiplication and division follow Fortran rules.
fdata-sections
-ffold-mem-offsets
-fcompare-elim -fcprop-registers -fcrossjumping
-fcse-follow-jumps -fcse-skip-blocks -fcx-fortran-rules
--fcx-limited-range
+-fcx-limited-range -fcx-method
-fdata-sections -fdce -fdelayed-branch
-fdelete-null-pointer-checks -fdevirtualize -fdevirtualize-speculatively
-fdevirtualize-at-ltrans -fdse
needed when performing complex division. Also, there is no checking
whether the result of a complex multiplication or division is @code{NaN
+ I*NaN}, with an attempt to rescue the situation in that case. The
-default is @option{-fno-cx-limited-range}, but is enabled by
-@option{-ffast-math}.
+option is enabled by @option{-ffast-math}.
This option controls the default setting of the ISO C99
@code{CX_LIMITED_RANGE} pragma. Nevertheless, the option applies to
whether the result of a complex multiplication or division is @code{NaN
+ I*NaN}, with an attempt to rescue the situation in that case.
-The default is @option{-fno-cx-fortran-rules}.
+@opindex fcx-method
+@item -fcx-method=@var{method}
+Complex multiplication and division follow the stated @var{method}. The
+@var{method} argument should be one of @samp{limited-range}, @samp{fortran}
+or @samp{stdc}.
+
+The default is to honor language specific constraints which means
+@samp{fortran} for Fortran and @samp{stdc} otherwise.
@end table
!= opt_for_fn (to->decl, flag_finite_math_only)
|| opt_for_fn (callee->decl, flag_signaling_nans)
!= opt_for_fn (to->decl, flag_signaling_nans)
- || opt_for_fn (callee->decl, flag_cx_limited_range)
- != opt_for_fn (to->decl, flag_cx_limited_range)
+ || opt_for_fn (callee->decl, flag_complex_method)
+ != opt_for_fn (to->decl, flag_complex_method)
|| opt_for_fn (callee->decl, flag_signed_zeros)
!= opt_for_fn (to->decl, flag_signed_zeros)
|| opt_for_fn (callee->decl, flag_associative_math)
= opt_for_fn (callee->decl, flag_finite_math_only);
opts.x_flag_signaling_nans
= opt_for_fn (callee->decl, flag_signaling_nans);
- opts.x_flag_cx_limited_range
- = opt_for_fn (callee->decl, flag_cx_limited_range);
+ opts.x_flag_complex_method
+ = opt_for_fn (callee->decl, flag_complex_method);
opts.x_flag_signed_zeros
= opt_for_fn (callee->decl, flag_signed_zeros);
opts.x_flag_associative_math
|| check_maybe_down (flag_unsafe_math_optimizations)
|| check_maybe_down (flag_finite_math_only)
|| check_maybe_up (flag_signaling_nans)
- || check_maybe_down (flag_cx_limited_range)
+ || check_maybe_up (flag_complex_method)
|| check_maybe_up (flag_signed_zeros)
|| check_maybe_down (flag_associative_math)
|| check_maybe_down (flag_reciprocal_math)
|| 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)
+ /* Use a frontend provided default for the complex eval method. */
+ if (!opts_set->x_flag_complex_method)
opts->x_flag_complex_method = opts->x_flag_default_complex_method;
/* Use -fvect-cost-model=cheap instead of -fvect-cost-mode=very-cheap
opts->x_flag_signaling_nans = 0;
if (!opts->frontend_set_flag_rounding_math)
opts->x_flag_rounding_math = 0;
- if (!opts->frontend_set_flag_cx_limited_range)
- opts->x_flag_cx_limited_range = 1;
+ if (!opts->frontend_set_flag_complex_method)
+ opts->x_flag_complex_method = 0;
}
}
--- /dev/null
+/* { dg-lto-do link } */
+/* { dg-lto-options { { -O -flto -fdump-tree-optimized } } } */
+
+_Complex double bar (_Complex double x, _Complex double y);
+
+_Complex double foo (_Complex double x, _Complex double y)
+{
+ return x / y;
+}
+
+volatile double r;
+
+int main ()
+{
+ _Complex double x = r + 1.0iF * r;
+ _Complex double y = r + 1.0iF * r;
+ _Complex double z = foo (x, y);
+ volatile _Complex double w = bar (z, x);
+}
+
+/* { dg-final { scan-ltrans-tree-dump-times "divdc3" 1 "optimized" } } */
--- /dev/null
+/* { dg-options "-fcx-limited-range" } */
+
+_Complex double bar (_Complex double x, _Complex double y)
+{
+ return x / y;
+}