@@ -2502,6 +2502,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx
rtx i3dest_killed = 0;
/* SET_DEST and SET_SRC of I2, I1 and I0. */
rtx i2dest = 0, i2src = 0, i1dest = 0, i1src = 0, i0dest = 0, i0src = 0;
+ rtx i1src_copy = 0;
/* Set if I2DEST was reused as a scratch register. */
bool i2scratch = false;
/* The PATTERNs of I0, I1, and I2, or a copy of them in certain cases. */
@@ -3128,6 +3129,14 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx
return 0;
}
+ /* Following subst may modify i1src, make a copy of it
+ before it is for added_sets_2 handling if needed. */
+ if (added_sets_2
+ && i0dest_in_i0src
+ && i0_feeds_i1_n
+ && (i1_feeds_i2_n || i0_feeds_i2_n))
+ i1src_copy = copy_rtx (i1src);
+
n_occurrences = 0;
subst_low_luid = DF_INSN_LUID (i0);
newpat = subst (newpat, i0dest, i0src, 0,
@@ -3200,11 +3209,10 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx
if (added_sets_2)
{
rtx t = i2pat;
- if (i0_feeds_i2_n)
- t = subst (t, i0dest, i0src, 0, 0);
if (i1_feeds_i2_n)
- t = subst (t, i1dest, i1src, 0, 0);
- if (i0_feeds_i1_n && i1_feeds_i2_n)
+ t = subst (t, i1dest, i1src_copy ? i1src_copy : i1src, 0,
+ i0_feeds_i1_n && i0dest_in_i0src);
+ if ((i0_feeds_i1_n && i1_feeds_i2_n) || i0_feeds_i2_n)
t = subst (t, i0dest, i0src, 0, 0);
XVECEXP (newpat, 0, --total_sets) = t;
@@ -0,0 +1,14 @@
+/* PR rtl-optimization/46034 */
+
+void bar (int);
+
+void
+foo (int x, int y)
+{
+ int i;
+ for (i = 0; i < x; i++)
+ {
+ y = __builtin_abs (y);
+ bar (y / 2);
+ }
+}
@@ -0,0 +1,32 @@
+/* PR rtl-optimization/46248 */
+
+struct S
+{
+ int s;
+};
+
+void
+foo (unsigned char *x, int y, struct S *z)
+{
+ const int l1 = y;
+ const int l2 = y + l1;
+ const int l3 = y + l2;
+ const int l4 = y + l3;
+ const int l5 = y + l4;
+ const int l6 = y + l5;
+ const int l7 = y + l6;
+ int i;
+ for (i = 0; i < 8; i++)
+ {
+ int a = x[l3] - x[l4];
+ int b = x[l4] - x[l5];
+ int c = x[l5] - x[l6];
+ int d = (b >= 0 ? b : -b) - (((a >= 0 ? a : -a) + (c >= 0 ? c : -c)) >> 1);
+ if (d < z->s * 2)
+ {
+ int v = d * (-b > 0 ? 1 : -1);
+ x[l2] += v >> 3;
+ x[l7] -= v >> 3;
+ }
+ }
+}
@@ -0,0 +1,23 @@
+/* PR rtl-optimization/46212 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -funroll-loops" } */
+/* { dg-options "-O3 -funroll-loops -march=i386" { target { { i686-*-* x86_64-*-* } && ilp32 } } } */
+
+static inline unsigned
+foo (void *x)
+{
+ unsigned y = *(volatile unsigned *) (x);
+ return (y >> 24) | ((y >> 8) & 0xff00) | ((y & 0xff00) << 8) | (y << 24);
+}
+
+void
+bar (void *x, void *y, int z)
+{
+ unsigned c;
+ while (z--)
+ {
+ c = foo (y);
+ *(unsigned *) x = (c & 0xf80000) >> 9 | (c & 0xf800) >> 6
+ | (c & 0xf8) >> 3 | (c & 0x80000000) >> 16;
+ }
+}