diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-04 10:56:22 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-04 10:56:22 +0000 |
commit | b9be572eda05cd23bbabd6409387d2c7ac782715 (patch) | |
tree | 5b089e25b51a9c3914b5055c84f8d83414072dab /gcc/builtins.c | |
parent | 2fee2038f99cb244aa1250f8ad42cae7fe2702ec (diff) | |
download | gcc-b9be572eda05cd23bbabd6409387d2c7ac782715.tar.gz |
2010-11-04 Richard Guenther <rguenther@suse.de>
Richard Henderson <rth@redhat.com>
* tree.def (FMA_EXPR): New tree code.
* expr.c (expand_expr_real_2): Add FMA_EXPR expansion code.
* gimple.c (gimple_rhs_class_table): FMA_EXPR is a GIMPLE_TERNARY_RHS.
* tree-cfg.c (verify_gimple_assign_ternary): Verify FMA_EXPR types.
* tree-inline.c (estimate_operator_cost): Handle FMA_EXPR.
* gimple-pretty-print.c (dump_ternary_rhs): Likewise.
* tree-ssa-math-opts.c (convert_mult_to_fma): New function.
(execute_optimize_widening_mul): Call it. Reorganize to allow
dead stmt removal. Move TODO flags ...
(pass_optimize_widening_mul): ... here.
* flag-types.h (enum fp_contract_mode): New enum.
* common.opt (flag_fp_contract_mode): New variable.
(-ffp-contract): New option.
* opts.c (common_handle_option): Handle it.
* doc/invoke.texi (-ffp-contract): Document.
* tree.h (fold_fma): Declare.
* builtins.c (fold_fma): New function.
(fold_builtin_fma): Likewise.
(fold_builtin_3): Call it for fma.
* fold-const.c (fold_ternary_loc): Fold FMA_EXPR.
* optabs.c (optab_for_tree_code): Handle FMA_EXPR.
* config/i386/sse.md (fms<mode>4, fnma<mode>, fnms<mode>4):
New expanders.
* doc/md.texi (fms<mode>4, fnma<mode>, fnms<mode>4): Document new
named patterns.
* genopinit.c (optabs): Initialize fms_optab, fnma_optab and fnms_optab.
* optabs.h (enum optab_index): Add OTI_fms, OTI_fnma and OTI_fnms.
(fms_optab, fnma_optab, fnms_optab): New defines.
* gimplify.c (gimplify_expr): Handle binary truth expressions
explicitly. Handle FMA_EXPR.
* tree-vect-stmts.c (vectorizable_operation): Handle ternary
operations.
* gcc.target/i386/fma4-vector-2.c: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@166304 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index 31a869bf1f6..e193791ccc7 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -9266,6 +9266,40 @@ fold_builtin_abs (location_t loc, tree arg, tree type) return fold_build1_loc (loc, ABS_EXPR, type, arg); } +/* Fold a fma operation with arguments ARG[012]. */ + +tree +fold_fma (location_t loc ATTRIBUTE_UNUSED, + tree type, tree arg0, tree arg1, tree arg2) +{ + if (TREE_CODE (arg0) == REAL_CST + && TREE_CODE (arg1) == REAL_CST + && TREE_CODE (arg2) == REAL_CST) + return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma); + + return NULL_TREE; +} + +/* Fold a call to fma, fmaf, or fmal with arguments ARG[012]. */ + +static tree +fold_builtin_fma (location_t loc, tree arg0, tree arg1, tree arg2, tree type) +{ + if (validate_arg (arg0, REAL_TYPE) + && validate_arg(arg1, REAL_TYPE) + && validate_arg(arg2, REAL_TYPE)) + { + tree tem = fold_fma (loc, type, arg0, arg1, arg2); + if (tem) + return tem; + + /* ??? Only expand to FMA_EXPR if it's directly supported. */ + if (optab_handler (fma_optab, TYPE_MODE (type)) != CODE_FOR_nothing) + return fold_build3_loc (loc, FMA_EXPR, type, arg0, arg1, arg2); + } + return NULL_TREE; +} + /* Fold a call to builtin fmin or fmax. */ static tree @@ -10540,10 +10574,7 @@ fold_builtin_3 (location_t loc, tree fndecl, return fold_builtin_sincos (loc, arg0, arg1, arg2); CASE_FLT_FN (BUILT_IN_FMA): - if (validate_arg (arg0, REAL_TYPE) - && validate_arg(arg1, REAL_TYPE) - && validate_arg(arg2, REAL_TYPE)) - return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma); + return fold_builtin_fma (loc, arg0, arg1, arg2, type); break; CASE_FLT_FN (BUILT_IN_REMQUO): |