From: Jakub Jelinek Date: Wed, 25 Aug 2010 17:50:59 +0000 (+0200) Subject: re PR rtl-optimization/44858 (likely integer wrong code bug) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ea9f1d6fe5de833116b1e34300c17082ba8e1704;p=gcc.git re PR rtl-optimization/44858 (likely integer wrong code bug) PR rtl-optimization/44858 * combine.c (try_combine): If recog_for_combine added CLOBBERs to newi2pat, make sure they don't affect newpat. * gcc.c-torture/execute/pr44858.c: New test. From-SVN: r163552 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1123d07ce20..0cdd6aaba95 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2010-08-25 Jakub Jelinek + PR rtl-optimization/44858 + * combine.c (try_combine): If recog_for_combine added CLOBBERs to + newi2pat, make sure they don't affect newpat. + PR rtl-optimization/45400 * combine.c (simplify_shift_const_1) : Only use SUBREG_REG if both modes are of MODE_INT class. diff --git a/gcc/combine.c b/gcc/combine.c index acff54198e5..273a9820df8 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -3725,7 +3725,58 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p) i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes); if (i2_code_number >= 0) - insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); + { + /* recog_for_combine might have added CLOBBERs to newi2pat. + Make sure NEWPAT does not depend on the clobbered regs. */ + 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)) + break; + } + + 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); + } } /* If it still isn't recognized, fail and change things back the way they diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fd9f5ad3d0a..15dad787aff 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2010-08-25 Jakub Jelinek + PR rtl-optimization/44858 + * gcc.c-torture/execute/pr44858.c: New test. + PR rtl-optimization/45400 * g++.dg/other/i386-8.C: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr44858.c b/gcc/testsuite/gcc.c-torture/execute/pr44858.c new file mode 100644 index 00000000000..45e1758b0c2 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr44858.c @@ -0,0 +1,28 @@ +/* PR rtl-optimization/44858 */ + +extern void abort (void); +int a = 3; +int b = 1; + +__attribute__((noinline)) long long +foo (int x, int y) +{ + return x / y; +} + +__attribute__((noinline)) int +bar (void) +{ + int c = 2; + c &= foo (1, b) > b; + b = (a != 0) | c; + return c; +} + +int +main (void) +{ + if (bar () != 0 || b != 1) + abort (); + return 0; +}