This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] combine.c: Fix rtl-optimization/27477.


Hi,

Attached is a patch to fix rtl-optimization/27477.

If you compile the attached testcase, the combiner comes up with:

(parallel [(set (pc)
		(if_then_else (ne (cc0)
				  (const_int 0))
			      (label_ref:SI 39)
			      (pc)))
	   (set (reg:HI 21)
		(eq:HI (cc0)
		       (const_int 0)))
	   ])

Note that both sets in this parallel references cc0.  Since this insn
is not recognized, the combiner tries to split the insn into two
individual sets like so:

(set (pc)
     (if_then_else (ne (cc0)
		       (const_int 0))
		   (label_ref:SI 39)
		   (pc)))

(set (reg:HI 21)
     (eq:HI (cc0)
	    (const_int 0)))

Note that the second insn references cc0 even though it does not
immediately follow the cc0 user.  Also, a jump insn is not at the end
of a basic block.

The patch solves this problem by refusing to split a parallel of two
sets if both sets references cc0.

With this patch, the build of h8300-none-elf goes further.  OK to apply?

Kazu Hirata

2006-05-17  Kazu Hirata  <kazu@codesourcery.com>

	PR rtl-optimization/27477
	* combine.c (try_combine): Don't split a parallel consisting
	of two sets into two individual sets if both sets reference
	cc0.

Index: combine.c
===================================================================
--- combine.c	(revision 113609)
+++ combine.c	(working copy)
@@ -2896,7 +2896,14 @@ try_combine (rtx i3, rtx i2, rtx i1, int
 	   && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 0)),
 				  XVECEXP (newpat, 0, 1))
 	   && ! (contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 0)))
-		 && contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 1)))))
+		 && contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 1))))
+#ifdef HAVE_cc0
+	   /* We cannot split the parallel into two sets if both sets
+	      reference cc0.  */
+	   && ! (reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 0))
+		 && reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 1)))
+#endif
+	   )
     {
       /* Normally, it doesn't matter which of the two is done first,
 	 but it does if one references cc0.  In that case, it has to


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]