From: rth Date: Tue, 19 Oct 2010 02:12:07 +0000 (+0000) Subject: * simplify-rtx.c (simplify_ternary_operation) [FMA]: Simplify X-Git-Tag: upstream/4.9.2~25634 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5d4d1c964920aadb1e2af6f8201ec111995b0603;p=platform%2Fupstream%2Flinaro-gcc.git * simplify-rtx.c (simplify_ternary_operation) [FMA]: Simplify (fma (neg a) (neg b) c) and (fma a (neg b) c). git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@165677 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8f1595d..d044941 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2010-10-18 Richard Henderson + * simplify-rtx.c (simplify_ternary_operation) [FMA]: Simplify + (fma (neg a) (neg b) c) and (fma a (neg b) c). + +2010-10-18 Richard Henderson + * config/i386/i386.c (IX86_BUILTIN_VFMSUBSS, IX86_BUILTIN_VFMSUBSD, IX86_BUILTIN_VFMSUBPS, IX86_BUILTIN_VFMSUBPD, IX86_BUILTIN_VFMSUBADDPS, IX86_BUILTIN_VFMSUBADDPD, diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index f700958..e45917f 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -4705,6 +4705,8 @@ simplify_ternary_operation (enum rtx_code code, enum machine_mode mode, rtx op2) { unsigned int width = GET_MODE_BITSIZE (mode); + bool any_change = false; + rtx tem; /* VOIDmode means "infinite" precision. */ if (width == 0) @@ -4712,10 +4714,29 @@ simplify_ternary_operation (enum rtx_code code, enum machine_mode mode, switch (code) { - /* At present, don't simplify fused multiply and add ops, because we need - to make sure there are no intermediate rounding steps used, and that - we get the right sign if negative 0 would be returned. */ case FMA: + /* Simplify negations around the multiplication. */ + /* -a * -b + c => a * b + c. */ + if (GET_CODE (op0) == NEG) + { + tem = simplify_unary_operation (NEG, mode, op1, mode); + if (tem) + op1 = tem, op0 = XEXP (op0, 0), any_change = true; + } + else if (GET_CODE (op1) == NEG) + { + tem = simplify_unary_operation (NEG, mode, op0, mode); + if (tem) + op0 = tem, op1 = XEXP (op1, 0), any_change = true; + } + + /* Canonicalize the two multiplication operands. */ + /* a * -b + c => -b * a + c. */ + if (swap_commutative_operands_p (op0, op1)) + tem = op0, op0 = op1, op1 = tem, any_change = true; + + if (any_change) + return gen_rtx_FMA (mode, op0, op1, op2); return NULL_RTX; case SIGN_EXTRACT: