https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95060

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Version|unknown                     |11.0
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2020-05-12
           Keywords|                            |missed-optimization
     Ever confirmed|0                           |1
             Target|                            |x86_64-*-* i?86-*-*

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
FMA generation already folds the FMA stmt:

      if (cond)
        fma_stmt = gimple_build_call_internal (IFN_COND_FMA, 5, cond, mulop1,
                                               op2, addop, else_value);
      else
        fma_stmt = gimple_build_call_internal (IFN_FMA, 3, mulop1, op2, addop);
      gimple_set_lhs (fma_stmt, gimple_get_lhs (use_stmt));
      gimple_call_set_nothrow (fma_stmt, !stmt_can_throw_internal (cfun,
                                                                   use_stmt));
      gsi_replace (&gsi, fma_stmt, true);
      /* Follow all SSA edges so that we generate FMS, FNMA and FNMS
         regardless of where the negation occurs.  */
      gimple *orig_stmt = gsi_stmt (gsi);
      if (fold_stmt (&gsi, follow_all_ssa_edges))
        {
          if (maybe_clean_or_replace_eh_stmt (orig_stmt, gsi_stmt (gsi)))
            gcc_unreachable ();
          update_stmt (gsi_stmt (gsi));

but not the negate it feeds since with -ffast-math we have
-((a[i] * b[i]) + c[i]) as canonical form it seems (reassoc does this).

float r[8], a[8], b[8], c[8];

void
test_fnms (void)
{
  for (int i = 0; i < 8; i++)
    r[i] = -((a[i] * b[i]) + c[i]);
}

would be an alternative testcase, not handled without -ffast-math either.

I'd suggest to fold the single-use stmt of the fma_stmts lhs if any
[and if it is a negate].

Reply via email to