https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111098
Bug ID: 111098 Summary: Missed combine .FMA + .COND_NEG Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: lehua.ding at rivai dot ai Target Milestone: --- For code[1], GCC first combine a[i] + b[i] * c to a .FMA (widening_mul pass) than fold .FMA + neg to .FNMS. But for code[2], it not fold .FMA + .COND_NEG to .COND_FNMS. See the codes and dump tree on https://godbolt.org/z/WTKrET4sn. Can we relax the fold condition after fuse mul+add from neg to neg or COND_NEG? The simple try is as diff[3]. [1] r[i] = -(a[i] + b[i] * c); [2] r[i] = pred[i] != 1 ? -(a[i] + b[i] * c) : c; [3] diff --git a/gcc/match.pd b/gcc/match.pd index 86fdc606a79..a3719f725ab 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -8020,7 +8020,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (simplify (negate (fmas@3 @0 @1 @2)) (if (single_use (@3)) - (IFN_FNMS @0 @1 @2)))) + (IFN_FNMS @0 @1 @2))) + (simplify + (IFN_COND_NEG @0 (fmas@5 @1 @2 @3) @4) + (if (single_use (@5)) + (IFN_COND_FNMS @0 @1 @2 @3 @4)))) (simplify (IFN_FMS:c (negate @0) @1 @2) diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc index 712097ac5be..b9f9baba002 100644 --- a/gcc/tree-ssa-math-opts.cc +++ b/gcc/tree-ssa-math-opts.cc @@ -3163,8 +3163,10 @@ convert_mult_to_fma_1 (tree mul_result, tree op1, tree op2) && gimple_call_lhs (orig_stmt) && TREE_CODE (gimple_call_lhs (orig_stmt)) == SSA_NAME && single_imm_use (gimple_call_lhs (orig_stmt), &use_p, &neg_stmt) - && is_gimple_assign (neg_stmt) - && gimple_assign_rhs_code (neg_stmt) == NEGATE_EXPR + && ((is_gimple_assign (neg_stmt) + && gimple_assign_rhs_code (neg_stmt) == NEGATE_EXPR) + || (gimple_call_internal_p (neg_stmt) + && gimple_call_internal_fn (neg_stmt) == IFN_COND_NEG)) && !stmt_could_throw_p (cfun, neg_stmt)) { gsi = gsi_for_stmt (neg_stmt);