+2018-07-30 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR rtl-optimization/85160
+ * combine.c (is_just_move): New function.
+ (try_combine): Allow combining two instructions into two if neither of
+ the original instructions was a move.
+
2018-07-30 Alexander Monakov <amonakov@ispras.ru>
PR target/86673
return true;
}
+/* Return whether X is just a single set, with the source
+ a general_operand. */
+static bool
+is_just_move (rtx x)
+{
+ if (INSN_P (x))
+ x = PATTERN (x);
+
+ return (GET_CODE (x) == SET && general_operand (SET_SRC (x), VOIDmode));
+}
+
/* Try to combine the insns I0, I1 and I2 into I3.
Here I0, I1 and I2 appear earlier than I3.
I0 and I1 can be zero; then we combine just I2 into I3, or I1 and I2 into
int swap_i2i3 = 0;
int split_i2i3 = 0;
int changed_i3_dest = 0;
+ bool i2_was_move = false, i3_was_move = false;
int maxreg;
rtx_insn *temp_insn;
return 0;
}
+ /* Record whether i2 and i3 are trivial moves. */
+ i2_was_move = is_just_move (i2);
+ i3_was_move = is_just_move (i3);
+
/* Record whether I2DEST is used in I2SRC and similarly for the other
cases. Knowing this will help in register status updating below. */
i2dest_in_i2src = reg_overlap_mentioned_p (i2dest, i2src);
&& XVECLEN (newpat, 0) == 2
&& GET_CODE (XVECEXP (newpat, 0, 0)) == SET
&& GET_CODE (XVECEXP (newpat, 0, 1)) == SET
- && (i1 || set_noop_p (XVECEXP (newpat, 0, 0))
- || set_noop_p (XVECEXP (newpat, 0, 1)))
+ && (i1
+ || set_noop_p (XVECEXP (newpat, 0, 0))
+ || set_noop_p (XVECEXP (newpat, 0, 1))
+ || (!i2_was_move && !i3_was_move))
&& GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != ZERO_EXTRACT
&& GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != STRICT_LOW_PART
&& GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != ZERO_EXTRACT