diff options
author | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-08-25 14:14:59 +0000 |
---|---|---|
committer | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-08-25 14:14:59 +0000 |
commit | dcbd909c20b0f045f606448f068d75ac1bd3ee8f (patch) | |
tree | fc7abd9a5867b5301f6c577a01296f62b18e5e16 /gcc/combine.c | |
parent | 24621f7a9d1f9fce6e3d7bb72c273adb02f392d0 (diff) | |
download | gcc-dcbd909c20b0f045f606448f068d75ac1bd3ee8f.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@163547 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/combine.c')
-rw-r--r-- | gcc/combine.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index f144d1e8f28..94e68392d98 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. */ |