http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59385
--- Comment #5 from Sriraman Tallam <tmsriram at google dot com> ---
The root-cause is because floating point expression contraction is default
disabled in ISO C unless specified explicitly. So, adding -ffp-contract=fast
solves the problem.
Details:
The problem is in function convert_mult_to_fma in tree-ssa-math-opts.c. This
does not try to convert the mult into an fma expression because:
static bool
convert_mult_to_fma (gimple mul_stmt, tree op1, tree op2)
{
tree mul_result = gimple_get_lhs (mul_stmt);
tree type = TREE_TYPE (mul_result);
gimple use_stmt, neguse_stmt, fma_stmt;
use_operand_p use_p;
imm_use_iterator imm_iter;
if (FLOAT_TYPE_P (type)
&& flag_fp_contract_mode == FP_CONTRACT_OFF)
return false;
Here, flag_fp_contract_mode is set to FP_CONTRACT_OFF even though it was
initialized to FP_CONTRACT_FAST.
flag_fp_contract_mode gets reset to FP_CONTRACT_OFF here:
c-family/c-opts.c:
bool
c_common_post_options (const char **pfilename)
{
...
/* ISO C restricts floating-point expression contraction to within
source-language expressions (-ffp-contract=on, currently an alias
for -ffp-contract=off). */
if (flag_iso
&& !c_dialect_cxx ()
&& (global_options_set.x_flag_fp_contract_mode
== (enum fp_contract_mode) 0))
flag_fp_contract_mode = FP_CONTRACT_OFF;
That happened in rev. 204460. I do not understand this restriction. However,
specifying -ffp-contract=fast in the command-line disables this reset.