diff mbox

[6/6] combine: allow combining two insns into two in some cases (PR52714)

Message ID 5030840454fd7bbd071e868121a946eaa3e03338.1417135738.git.segher@kernel.crashing.org
State New
Headers show

Commit Message

Segher Boessenkool Nov. 28, 2014, 1:44 a.m. UTC
If one of the resulting insns is a noop set it is safe to allow the
combination, for it will never lead to a loop: any following combination
using that noop will delete it.  In fact, in most cases combine deletes
the noop immediately; for cc0 targets it does not in some cases, but it
deletes another insn in that case (a following jump insn).

This fixes PR52714.


2014-11-27  Segher Boessenkool  <segher@kernel.crashing.org>

gcc/
	PR rtl-optimization/52714
	* combine.c (try_combine): Allow combining two insns into two
	new insns if at least one of those is a noop.

---
 gcc/combine.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

Comments

Jeff Law Dec. 1, 2014, 5:39 p.m. UTC | #1
On 11/27/14 18:44, Segher Boessenkool wrote:
> If one of the resulting insns is a noop set it is safe to allow the
> combination, for it will never lead to a loop: any following combination
> using that noop will delete it.  In fact, in most cases combine deletes
> the noop immediately; for cc0 targets it does not in some cases, but it
> deletes another insn in that case (a following jump insn).
>
> This fixes PR52714.
>
>
> 2014-11-27  Segher Boessenkool  <segher@kernel.crashing.org>
>
> gcc/
> 	PR rtl-optimization/52714
> 	* combine.c (try_combine): Allow combining two insns into two
> 	new insns if at least one of those is a noop.
Also OK with a testcase.  I'd recommend just using the one from 52714, 
make it m68k specific.  Not sure if it's best to scan the assembly or 
.combine dump -- your call.

jeff
diff mbox

Patch

diff --git a/gcc/combine.c b/gcc/combine.c
index 91ddff4..66007d8 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -3812,15 +3812,20 @@  try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
   /* Similarly, check for a case where we have a PARALLEL of two independent
      SETs but we started with three insns.  In this case, we can do the sets
      as two separate insns.  This case occurs when some SET allows two
-     other insns to combine, but the destination of that SET is still live.  */
+     other insns to combine, but the destination of that SET is still live.
 
-  else if (i1 && insn_code_number < 0 && asm_noperands (newpat) < 0
+     Also do this if we started with two insns and (at least) one of the
+     resulting sets is a noop; this noop will be deleted later.  */
+
+  else if (insn_code_number < 0 && asm_noperands (newpat) < 0
 	   && GET_CODE (newpat) == PARALLEL
 	   && 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)))
 	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != ZERO_EXTRACT
 	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != STRICT_LOW_PART
-	   && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
 	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != ZERO_EXTRACT
 	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART
 	   && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 1)),