From 522ca5400502ca857adab503693ef095aaf9a1bc Mon Sep 17 00:00:00 2001 From: ebotcazou Date: Sun, 13 Oct 2013 13:29:28 +0000 Subject: [PATCH] PR rtl-optimization/58662 * combine.c (try_combine): Take into account death nodes on I2 when splitting a PARALLEL of two independent SETs. Fix dump message. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@203498 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++++ gcc/combine.c | 43 +++++++++++++++++---------- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.c-torture/execute/pr58662.c | 22 ++++++++++++++ 4 files changed, 59 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr58662.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5ad86db..2f0bfce 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-10-13 Eric Botcazou + + PR rtl-optimization/58662 + * combine.c (try_combine): Take into account death nodes on I2 when + splitting a PARALLEL of two independent SETs. Fix dump message. + 2013-10-12 Oleg Endo PR target/51244 diff --git a/gcc/combine.c b/gcc/combine.c index fcf60cd..13f5e29 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -3693,29 +3693,42 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p, && ! (contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 0))) && contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 1))))) { + rtx set0 = XVECEXP (newpat, 0, 0); + rtx set1 = XVECEXP (newpat, 0, 1); + /* Normally, it doesn't matter which of the two is done first, 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)) + be first. The PARALLEL might also have been pre-existing in i3, + so we need to make sure that we won't wrongly hoist a SET to i2 + that would conflict with a death note present in there. */ + if (!use_crosses_set_p (SET_SRC (set1), DF_INSN_LUID (i2)) + && !(REG_P (SET_DEST (set1)) + && find_reg_note (i2, REG_DEAD, SET_DEST (set1))) + && !(GET_CODE (SET_DEST (set1)) == SUBREG + && find_reg_note (i2, REG_DEAD, + SUBREG_REG (SET_DEST (set1)))) #ifdef HAVE_cc0 - && !reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 0)) + && !reg_referenced_p (cc0_rtx, set0) #endif ) { - newi2pat = XVECEXP (newpat, 0, 1); - newpat = XVECEXP (newpat, 0, 0); + newi2pat = set1; + newpat = set0; } - else if (!use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 0)), - DF_INSN_LUID (i2)) + else if (!use_crosses_set_p (SET_SRC (set0), DF_INSN_LUID (i2)) + && !(REG_P (SET_DEST (set0)) + && find_reg_note (i2, REG_DEAD, SET_DEST (set0))) + && !(GET_CODE (SET_DEST (set0)) == SUBREG + && find_reg_note (i2, REG_DEAD, + SUBREG_REG (SET_DEST (set0)))) #ifdef HAVE_cc0 - && !reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 1)) + && !reg_referenced_p (cc0_rtx, set1) #endif ) { - newi2pat = XVECEXP (newpat, 0, 0); - newpat = XVECEXP (newpat, 0, 1); + newi2pat = set0; + newpat = set1; } else { @@ -4261,9 +4274,8 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p, } /* Update reg_stat[].nonzero_bits et al for any changes that may have - been made to this insn. The order of - set_nonzero_bits_and_sign_copies() is important. Because newi2pat - can affect nonzero_bits of newpat */ + been made to this insn. The order is important, because newi2pat + can affect nonzero_bits of newpat. */ if (newi2pat) note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL); note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL); @@ -4283,7 +4295,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p, { if (dump_file) { - fprintf (dump_file, "modifying insn i1 "); + fprintf (dump_file, "modifying insn i0 "); dump_insn_slim (dump_file, i0); } df_insn_rescan (i0); @@ -4321,7 +4333,6 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p, /* Set new_direct_jump_p if a new return or simple jump instruction has been created. Adjust the CFG accordingly. */ - if (returnjump_p (i3) || any_uncondjump_p (i3)) { *new_direct_jump_p = 1; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 07e2d4c..362186f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2013-10-13 Richard Biener + + * gcc.c-torture/execute/pr58662.c: New test. + 2013-10-12 Oleg Endo PR target/51244 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr58662.c b/gcc/testsuite/gcc.c-torture/execute/pr58662.c new file mode 100644 index 0000000..dc0d5f0 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr58662.c @@ -0,0 +1,22 @@ +extern void abort (void); + +int a, c, d; +volatile int b; + +static int +foo (int p1, short p2) +{ + return p1 / p2; +} + +int +main () +{ + char e; + d = foo (a == 0, (0, 35536)); + e = d % 14; + b = e && c; + if (b != 0) + abort (); + return 0; +} -- 2.7.4