From 2960be837a8b9b479615f41802e235b84ac294e7 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 20 Sep 2010 15:24:23 +0200 Subject: re PR rtl-optimization/45695 (-O1 wrong-code by cmove) 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. From-SVN: r164431 --- gcc/ChangeLog | 7 +++ gcc/combine.c | 76 +++++++++------------------ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.c-torture/execute/pr45695.c | 32 +++++++++++ 4 files changed, 68 insertions(+), 52 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr45695.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 00504dd..9b35e74 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2010-09-20 Jakub Jelinek + + 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. + 2010-09-19 Jan Hubicka PR lto/44246 diff --git a/gcc/combine.c b/gcc/combine.c index 618e07d..6131b41 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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bf28866..4c8c62c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-09-20 Jakub Jelinek + + PR rtl-optimization/45695 + * gcc.c-torture/execute/pr45695.c: New test. + 2010-09-19 Jan Hubicka PR lto/44246 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr45695.c b/gcc/testsuite/gcc.c-torture/execute/pr45695.c new file mode 100644 index 0000000..eb1e4c7 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr45695.c @@ -0,0 +1,32 @@ +/* PR rtl-optimization/45695 */ + +extern void abort (void); + +__attribute__((noinline)) void +g (int x) +{ + asm volatile ("" : "+r" (x)); +} + +__attribute__((noinline)) int +f (int a, int b, int d) +{ + int r = -1; + b += d; + if (d == a) + r = b - d; + g (b); + return r; +} + +int +main (void) +{ + int l; + asm ("" : "=r" (l) : "0" (0)); + if (f (l + 0, l + 1, l + 4) != -1) + abort (); + if (f (l + 4, l + 1, l + 4) != 1) + abort (); + return 0; +} -- cgit v1.1