aboutsummaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authorBernd Schmidt <bernds@codesourcery.com>2010-08-25 14:14:59 +0000
committerBernd Schmidt <bernds@gcc.gnu.org>2010-08-25 14:14:59 +0000
commit0cdf7b49f10deeba7d5ba2ab3cedd4625718efef (patch)
treefc7abd9a5867b5301f6c577a01296f62b18e5e16 /gcc/combine.c
parent4942fc569c5ba8ab9bebfad2d9cc9630a69c2579 (diff)
downloadgcc-0cdf7b49f10deeba7d5ba2ab3cedd4625718efef.zip
gcc-0cdf7b49f10deeba7d5ba2ab3cedd4625718efef.tar.gz
gcc-0cdf7b49f10deeba7d5ba2ab3cedd4625718efef.tar.bz2
combine.c (find_split_point): Undo canonicalization of multiply-add to (minus x (mult)) when...
* combine.c (find_split_point): Undo canonicalization of multiply-add to (minus x (mult)) when it seems likely that this will increase the chances of a split. * gcc.target/i386/combine-mul.c: New test. From-SVN: r163547
Diffstat (limited to 'gcc/combine.c')
-rw-r--r--gcc/combine.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index f144d1e..94e6839 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -4771,6 +4771,23 @@ find_split_point (rtx *loc, rtx insn, bool set_src)
case PLUS:
case MINUS:
+ /* Canonicalization can produce (minus A (mult B C)), where C is a
+ constant. It may be better to try splitting (plus (mult B -C) A)
+ instead if this isn't a multiply by a power of two. */
+ if (set_src && code == MINUS && GET_CODE (XEXP (x, 1)) == MULT
+ && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
+ && exact_log2 (INTVAL (XEXP (XEXP (x, 1), 1))) < 0)
+ {
+ enum machine_mode mode = GET_MODE (x);
+ unsigned HOST_WIDE_INT this_int = INTVAL (XEXP (XEXP (x, 1), 1));
+ HOST_WIDE_INT other_int = trunc_int_for_mode (-this_int, mode);
+ SUBST (*loc, gen_rtx_PLUS (mode, gen_rtx_MULT (mode,
+ XEXP (XEXP (x, 1), 0),
+ GEN_INT (other_int)),
+ XEXP (x, 0)));
+ return find_split_point (loc, insn, set_src);
+ }
+
/* Split at a multiply-accumulate instruction. However if this is
the SET_SRC, we likely do not have such an instruction and it's
worthless to try this split. */