This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix combine EH related failure
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 12 Feb 2004 11:39:32 +1030
- Subject: 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