diff options
author | Bernd Schmidt <bernds@codesourcery.com> | 2010-08-25 14:14:59 +0000 |
---|---|---|
committer | Bernd Schmidt <bernds@gcc.gnu.org> | 2010-08-25 14:14:59 +0000 |
commit | 0cdf7b49f10deeba7d5ba2ab3cedd4625718efef (patch) | |
tree | fc7abd9a5867b5301f6c577a01296f62b18e5e16 | |
parent | 4942fc569c5ba8ab9bebfad2d9cc9630a69c2579 (diff) | |
download | gcc-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
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/combine.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/combine-mul.c | 23 |
4 files changed, 48 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e13577d..551e93b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -4,6 +4,10 @@ * combine.c (try_combine): Use reg_overlap_mentioned_p rather than dead_or_set_p when computing i0_feeds_i2_n. + * 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. + 2010-08-25 Richard Guenther <rguenther@suse.de> PR lto/44562 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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6e8b140..a3153af 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-08-25 Bernd Schmidt <bernds@codesourcery.com> + + * gcc.target/i386/combine-mul.c: New test. + 2010-08-25 Richard Guenther <rguenther@suse.de> PR lto/44562 diff --git a/gcc/testsuite/gcc.target/i386/combine-mul.c b/gcc/testsuite/gcc.target/i386/combine-mul.c new file mode 100644 index 0000000..4ef80e8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/combine-mul.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-not "12345" } } */ + +static inline unsigned int myrnd (void) +{ + static unsigned int s = 1388815473; + s *= 1103515245; + s += 12345; +} + +struct __attribute__ ((packed)) A { + unsigned short i:1, l:1, j:3, k:11; +}; + +struct A sA; +void testA (void) +{ + char *p = (char *) &sA; + *p++ = myrnd (); + *p++ = myrnd (); + sA.k = -1; +} |