diff options
Diffstat (limited to 'gcc/tree-ssa-math-opts.c')
-rw-r--r-- | gcc/tree-ssa-math-opts.c | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index 16d9399..273396d 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -2650,7 +2650,7 @@ convert_mult_to_fma_1 (tree mul_result, tree op1, tree op2) tree type = TREE_TYPE (mul_result); gimple *use_stmt; imm_use_iterator imm_iter; - gassign *fma_stmt; + gcall *fma_stmt; FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, mul_result) { @@ -2658,6 +2658,7 @@ convert_mult_to_fma_1 (tree mul_result, tree op1, tree op2) enum tree_code use_code; tree addop, mulop1 = op1, result = mul_result; bool negate_p = false; + gimple_seq seq = NULL; if (is_gimple_debug (use_stmt)) continue; @@ -2683,11 +2684,7 @@ convert_mult_to_fma_1 (tree mul_result, tree op1, tree op2) addop = gimple_assign_rhs2 (use_stmt); /* a * b - c -> a * b + (-c) */ if (gimple_assign_rhs_code (use_stmt) == MINUS_EXPR) - addop = force_gimple_operand_gsi (&gsi, - build1 (NEGATE_EXPR, - type, addop), - true, NULL_TREE, true, - GSI_SAME_STMT); + addop = gimple_build (&seq, NEGATE_EXPR, type, addop); } else { @@ -2698,23 +2695,26 @@ convert_mult_to_fma_1 (tree mul_result, tree op1, tree op2) } if (negate_p) - mulop1 = force_gimple_operand_gsi (&gsi, - build1 (NEGATE_EXPR, - type, mulop1), - true, NULL_TREE, true, - GSI_SAME_STMT); + mulop1 = gimple_build (&seq, NEGATE_EXPR, type, mulop1); - fma_stmt = gimple_build_assign (gimple_assign_lhs (use_stmt), - FMA_EXPR, mulop1, op2, addop); + if (seq) + gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT); + fma_stmt = gimple_build_call_internal (IFN_FMA, 3, mulop1, op2, addop); + gimple_call_set_lhs (fma_stmt, gimple_assign_lhs (use_stmt)); + gimple_call_set_nothrow (fma_stmt, !stmt_can_throw_internal (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. */ + if (fold_stmt (&gsi, follow_all_ssa_edges)) + update_stmt (gsi_stmt (gsi)); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Generated FMA "); - print_gimple_stmt (dump_file, fma_stmt, 0, 0); + print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, 0); fprintf (dump_file, "\n"); } - gsi_replace (&gsi, fma_stmt, true); widen_mul_stats.fmas_inserted++; } } @@ -2862,7 +2862,8 @@ convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2, /* If the target doesn't support it, don't generate it. We assume that if fma isn't available then fms, fnma or fnms are not either. */ - if (optab_handler (fma_optab, TYPE_MODE (type)) == CODE_FOR_nothing) + optimization_type opt_type = bb_optimization_type (gimple_bb (mul_stmt)); + if (!direct_internal_fn_supported_p (IFN_FMA, type, opt_type)) return false; /* If the multiplication has zero uses, it is kept around probably because @@ -2958,8 +2959,8 @@ convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2, that a mult / subtract pair. */ if (use_code == MINUS_EXPR && !negate_p && gimple_assign_rhs1 (use_stmt) == result - && optab_handler (fms_optab, TYPE_MODE (type)) == CODE_FOR_nothing - && optab_handler (fnma_optab, TYPE_MODE (type)) != CODE_FOR_nothing) + && !direct_internal_fn_supported_p (IFN_FMS, type, opt_type) + && direct_internal_fn_supported_p (IFN_FNMA, type, opt_type)) { tree rhs2 = gimple_assign_rhs2 (use_stmt); |