diff options
author | Richard Henderson <rth@redhat.com> | 2010-10-18 19:12:07 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2010-10-18 19:12:07 -0700 |
commit | 5c822194254910c3a04cf470a9a6469958447c1f (patch) | |
tree | 3565cd8c24aa466a4cd83d5bc718350c9919d8a6 /gcc | |
parent | 89509419968e2be6c7880a97968f07fab6b0e3b2 (diff) | |
download | gcc-5c822194254910c3a04cf470a9a6469958447c1f.zip gcc-5c822194254910c3a04cf470a9a6469958447c1f.tar.gz gcc-5c822194254910c3a04cf470a9a6469958447c1f.tar.bz2 |
simplify-rtx.c (simplify_ternary_operation): Simplify (fma (neg a) (neg b) c) and (fma a (neg b) c).
* simplify-rtx.c (simplify_ternary_operation) [FMA]: Simplify
(fma (neg a) (neg b) c) and (fma a (neg b) c).
From-SVN: r165677
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/simplify-rtx.c | 27 |
2 files changed, 29 insertions, 3 deletions
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 <rth@redhat.com> + * 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 <rth@redhat.com> + * 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: |