]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
combine.c (find_split_point): Undo canonicalization of multiply-add to (minus x ...
authorBernd Schmidt <bernds@codesourcery.com>
Wed, 25 Aug 2010 14:14:59 +0000 (14:14 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Wed, 25 Aug 2010 14:14:59 +0000 (14:14 +0000)
* 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

gcc/ChangeLog
gcc/combine.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/combine-mul.c [new file with mode: 0644]

index e13577d06bace7963b9b5a041b493c562ea07bd1..551e93b9f610104c34f3057c27983b6156793f1e 100644 (file)
@@ -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
index f144d1e8f2811c5ce281099dae94e8a1ad6780d1..94e68392d98b74c3abaeb8864d0f3dc84000031b 100644 (file)
@@ -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.  */
index 6e8b1407c28347b528f5d31b1caac77fb6bfd393..a3153af2613c4d7bc795f647713067e6692500cb 100644 (file)
@@ -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 (file)
index 0000000..4ef80e8
--- /dev/null
@@ -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;
+}