summaryrefslogtreecommitdiffstats
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-04 10:56:22 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-04 10:56:22 +0000
commitb9be572eda05cd23bbabd6409387d2c7ac782715 (patch)
tree5b089e25b51a9c3914b5055c84f8d83414072dab /gcc/builtins.c
parent2fee2038f99cb244aa1250f8ad42cae7fe2702ec (diff)
downloadppe42-gcc-b9be572eda05cd23bbabd6409387d2c7ac782715.tar.gz
ppe42-gcc-b9be572eda05cd23bbabd6409387d2c7ac782715.zip
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.c39
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):
OpenPOWER on IntegriCloud