From 5ed36cd587aef4299267d67c7aa5d5a339e83e1f Mon Sep 17 00:00:00 2001 From: jakub Date: Mon, 20 Sep 2010 13:24:23 +0000 Subject: PR rtl-optimization/45695 * combine.c (try_combine): When splitting a two set pattern, make sure the pattern which will be put into i2 doesn't use REGs or MEMs set by insns in between i2 and i3. * gcc.c-torture/execute/pr45695.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164431 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/combine.c | 76 +++++++++++++++++++---------------------------------------- 1 file changed, 24 insertions(+), 52 deletions(-) (limited to 'gcc/combine.c') diff --git a/gcc/combine.c b/gcc/combine.c index 618e07df4f0..6131b413d1d 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -3690,36 +3690,41 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p) && 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 - && ! use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 1)), - DF_INSN_LUID (i2)) && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 1)), XVECEXP (newpat, 0, 0)) && ! 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)))) -#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 - ) + && contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 1))))) { /* 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 + but the one that references cc0 can't be the second, and + one which uses any regs/memory set in between i2 and i3 can't be first. */ + if (!use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 1)), + DF_INSN_LUID (i2)) +#ifdef HAVE_cc0 + && !reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 0)) +#endif + ) + { + newi2pat = XVECEXP (newpat, 0, 1); + newpat = XVECEXP (newpat, 0, 0); + } + else if (!use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 0)), + DF_INSN_LUID (i2)) #ifdef HAVE_cc0 - if (reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 0))) + && !reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 1)) +#endif + ) { newi2pat = XVECEXP (newpat, 0, 0); newpat = XVECEXP (newpat, 0, 1); } else -#endif { - newi2pat = XVECEXP (newpat, 0, 1); - newpat = XVECEXP (newpat, 0, 0); + undo_all (); + return 0; } i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes); @@ -3735,44 +3740,11 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p) { rtx reg = XEXP (XVECEXP (newi2pat, 0, i), 0); if (reg_overlap_mentioned_p (reg, newpat)) - break; + { + undo_all (); + return 0; + } } - - if (i >= 0) - { - /* CLOBBERs on newi2pat prevent it going first. - Try the other order of the insns if possible. */ - temp = newpat; - newpat = XVECEXP (newi2pat, 0, 0); - newi2pat = temp; -#ifdef HAVE_cc0 - if (reg_referenced_p (cc0_rtx, newpat)) - { - undo_all (); - return 0; - } -#endif - - i2_code_number = recog_for_combine (&newi2pat, i2, - &new_i2_notes); - if (i2_code_number < 0) - { - undo_all (); - return 0; - } - - if (GET_CODE (newi2pat) == PARALLEL) - for (i = XVECLEN (newi2pat, 0) - 1; i >= 0; i--) - if (GET_CODE (XVECEXP (newi2pat, 0, i)) == CLOBBER) - { - rtx reg = XEXP (XVECEXP (newi2pat, 0, i), 0); - if (reg_overlap_mentioned_p (reg, newpat)) - { - undo_all (); - return 0; - } - } - } } insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); -- cgit v1.2.1