aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-math-opts.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-math-opts.c')
-rw-r--r--gcc/tree-ssa-math-opts.c37
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);