summaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authoramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2004-02-17 22:21:00 +0000
committeramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2004-02-17 22:21:00 +0000
commitfacad922b6daf41310fdd52ae4951c7541003475 (patch)
tree03e1c405e9d2d3e88aa509118732d9a60fa77386 /gcc/combine.c
parented869d6569bc24ab5007b946d3e2be6f8fec1761 (diff)
downloadgcc-facad922b6daf41310fdd52ae4951c7541003475.tar.gz
PR optimization/14119
* combine.c (try_combine): When attemting to fix unrecognized insns, don't delete SETs marked with REG_EH_REGION notes. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@77991 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/combine.c')
-rw-r--r--gcc/combine.c66
1 files changed, 36 insertions, 30 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index 3cf8ae076f1..a1219de570d 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -2017,7 +2017,8 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
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,37 +2034,42 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
{
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)))
- {
- newpat = set0;
- insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
- }
-
+ && 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)))))
+ && (!(note = find_reg_note (i3, REG_EH_REGION, NULL_RTX))
+ || INTVAL (XEXP (note, 0)) <= 0)
+ && ! side_effects_p (SET_SRC (set1)))
+ {
+ newpat = set0;
+ insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
+ }
+
else if (((GET_CODE (SET_DEST (set0)) == REG
- && find_reg_note (i3, REG_UNUSED, SET_DEST (set0)))
- || (GET_CODE (SET_DEST (set0)) == SUBREG
- && find_reg_note (i3, REG_UNUSED,
- SUBREG_REG (SET_DEST (set0)))))
- && ! side_effects_p (SET_SRC (set0)))
- {
- newpat = set1;
- insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
-
- if (insn_code_number >= 0)
- {
- /* If we will be able to accept this, we have made a
- change to the destination of I3. This requires us to
- do a few adjustments. */
-
- PATTERN (i3) = newpat;
- adjust_for_new_dest (i3);
- }
- }
+ && find_reg_note (i3, REG_UNUSED, SET_DEST (set0)))
+ || (GET_CODE (SET_DEST (set0)) == SUBREG
+ && find_reg_note (i3, REG_UNUSED,
+ SUBREG_REG (SET_DEST (set0)))))
+ && (!(note = find_reg_note (i3, REG_EH_REGION, NULL_RTX))
+ || INTVAL (XEXP (note, 0)) <= 0)
+ && ! side_effects_p (SET_SRC (set0)))
+ {
+ newpat = set1;
+ insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
+
+ if (insn_code_number >= 0)
+ {
+ /* If we will be able to accept this, we have made a
+ change to the destination of I3. This requires us to
+ do a few adjustments. */
+
+ PATTERN (i3) = newpat;
+ adjust_for_new_dest (i3);
+ }
+ }
}
/* If we were combining three insns and the result is a simple SET