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]

Fix combine EH related failure


Fixes http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14119

	PR optimization/14119
	* combine.c (try_combine): When attemting to fix unrecognized insns,
	don't delete SETs marked with REG_EH_REGION notes.  Also, don't split
	a PARALLEL when that results in the original insns.

Bootstrap and regression tests for powerpc64-linux, powerpc-linux,
i686-linux in progress.  OK for mainline and gcc-3.4 assuming no
regressions?

A testcase for this problem already exists in the testsuite, but doesn't
trigger at the moment due to testing libjava at -O0 and -O3.  Should we
test at -O0, -O1 and -O3?

Index: gcc/combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.408
diff -u -p -r1.408 combine.c
--- gcc/combine.c	3 Feb 2004 05:15:35 -0000	1.408
+++ gcc/combine.c	12 Feb 2004 00:54:40 -0000
@@ -2017,7 +2017,8 @@ try_combine (rtx i3, rtx i2, rtx i1, int
   insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
 
   /* If the result isn't valid, see if it is a PARALLEL of two SETs where
-     the second SET's destination is a register that is unused.  In that case,
+     the second SET's destination is a register that is unused and isn't
+     marked as an instruction that might trap in an EH region.  In that case,
      we just need the first SET.   This can occur when simplifying a divmod
      insn.  We *must* test for this case here because the code below that
      splits two independent SETs doesn't handle this case correctly when it
@@ -2033,12 +2034,20 @@ try_combine (rtx i3, rtx i2, rtx i1, int
     {
       rtx set0 = XVECEXP (newpat, 0, 0);
       rtx set1 = XVECEXP (newpat, 0, 1);
-  
+      rtx note;
+
       if (((GET_CODE (SET_DEST (set1)) == REG
             && find_reg_note (i3, REG_UNUSED, SET_DEST (set1)))
           || (GET_CODE (SET_DEST (set1)) == SUBREG
               && find_reg_note (i3, REG_UNUSED, SUBREG_REG (SET_DEST (set1)))))
-          && ! side_effects_p (SET_SRC (set1)))
+	  && (!(note = find_reg_note (i3, REG_EH_REGION, NULL_RTX))
+	      || INTVAL (XEXP (note, 0)) <= 0)
+          && ! side_effects_p (SET_SRC (set1))
+	  /* It's pointless doing this if combining then splitting the
+	     parallel results in the original instructions.  The net
+	     effect is only to move instructions around, which makes
+	     debug info less accurate.  */
+	  && ! rtx_equal_p (set0, PATTERN (i2)))
         {
           newpat = set0;
           insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
@@ -2049,7 +2058,10 @@ try_combine (rtx i3, rtx i2, rtx i1, int
                 || (GET_CODE (SET_DEST (set0)) == SUBREG
                     && find_reg_note (i3, REG_UNUSED,
                                       SUBREG_REG (SET_DEST (set0)))))
-              && ! side_effects_p (SET_SRC (set0)))
+	       && (!(note = find_reg_note (i3, REG_EH_REGION, NULL_RTX))
+		   || INTVAL (XEXP (note, 0)) <= 0)
+	       && ! side_effects_p (SET_SRC (set0))
+	       && ! rtx_equal_p (set1, PATTERN (i3)))
         {
           newpat = set1;
           insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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