* 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
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. */
--- /dev/null
+/* { 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;
+}