diff options
author | Jakub Jelinek <jakub@redhat.com> | 2008-10-08 10:12:25 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2008-10-08 10:12:25 +0200 |
commit | 31e9ebaf7fa9e80817bf1a87f670113a4e02309c (patch) | |
tree | c241c6387c5dd816585ab35e6ad1b285b82e88d5 | |
parent | a4a4f7755b77fb859050d11f62645d3a80a56ac8 (diff) | |
download | gcc-31e9ebaf7fa9e80817bf1a87f670113a4e02309c.zip gcc-31e9ebaf7fa9e80817bf1a87f670113a4e02309c.tar.gz gcc-31e9ebaf7fa9e80817bf1a87f670113a4e02309c.tar.bz2 |
re PR target/36635 (cc1 segfault from svn 137122)
PR target/36635
PR target/37290
PR rtl-optimization/37341
* cse.c (cse_cc_succs): Add ORIG_BB argument, don't follow edges
to ORIG_BB, pass through ORIG_BB recursively.
(cse_condition_code_reg): Adjust caller.
* gcc.c-torture/compile/pr37341.c: New test.
From-SVN: r140966
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cse.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr37341.c | 35 |
4 files changed, 64 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c7144e4..a4f09c8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2008-10-08 Jakub Jelinek <jakub@redhat.com> + + PR target/36635 + PR target/37290 + PR rtl-optimization/37341 + * cse.c (cse_cc_succs): Add ORIG_BB argument, don't follow edges + to ORIG_BB, pass through ORIG_BB recursively. + (cse_condition_code_reg): Adjust caller. + 2008-10-08 Kai Tietz <kai.tietz@onevision.com> * sdbout.c (sdbout_one_type): Treat the value type @@ -1,6 +1,6 @@ /* Common subexpression elimination for GNU compiler. Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998 - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of GCC. @@ -603,7 +603,8 @@ static bool set_live_p (rtx, rtx, int *); static int cse_change_cc_mode (rtx *, void *); static void cse_change_cc_mode_insn (rtx, rtx); static void cse_change_cc_mode_insns (rtx, rtx, rtx); -static enum machine_mode cse_cc_succs (basic_block, rtx, rtx, bool); +static enum machine_mode cse_cc_succs (basic_block, basic_block, rtx, rtx, + bool); #undef RTL_HOOKS_GEN_LOWPART @@ -6587,13 +6588,17 @@ cse_change_cc_mode_insns (rtx start, rtx end, rtx newreg) permitted to change the mode of CC_SRC to a compatible mode. This returns VOIDmode if no equivalent assignments were found. Otherwise it returns the mode which CC_SRC should wind up with. + ORIG_BB should be the same as BB in the outermost cse_cc_succs call, + but is passed unmodified down to recursive calls in order to prevent + endless recursion. The main complexity in this function is handling the mode issues. We may have more than one duplicate which we can eliminate, and we try to find a mode which will work for multiple duplicates. */ static enum machine_mode -cse_cc_succs (basic_block bb, rtx cc_reg, rtx cc_src, bool can_change_mode) +cse_cc_succs (basic_block bb, basic_block orig_bb, rtx cc_reg, rtx cc_src, + bool can_change_mode) { bool found_equiv; enum machine_mode mode; @@ -6624,7 +6629,9 @@ cse_cc_succs (basic_block bb, rtx cc_reg, rtx cc_src, bool can_change_mode) continue; if (EDGE_COUNT (e->dest->preds) != 1 - || e->dest == EXIT_BLOCK_PTR) + || e->dest == EXIT_BLOCK_PTR + /* Avoid endless recursion on unreachable blocks. */ + || e->dest == orig_bb) continue; end = NEXT_INSN (BB_END (e->dest)); @@ -6729,7 +6736,7 @@ cse_cc_succs (basic_block bb, rtx cc_reg, rtx cc_src, bool can_change_mode) { enum machine_mode submode; - submode = cse_cc_succs (e->dest, cc_reg, cc_src, false); + submode = cse_cc_succs (e->dest, orig_bb, cc_reg, cc_src, false); if (submode != VOIDmode) { gcc_assert (submode == mode); @@ -6857,7 +6864,7 @@ cse_condition_code_reg (void) the basic block. */ orig_mode = GET_MODE (cc_src); - mode = cse_cc_succs (bb, cc_reg, cc_src, true); + mode = cse_cc_succs (bb, bb, cc_reg, cc_src, true); if (mode != VOIDmode) { gcc_assert (mode == GET_MODE (cc_src)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cc7ec16..031441e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2008-10-08 Jakub Jelinek <jakub@redhat.com> + + PR target/36635 + PR target/37290 + PR rtl-optimization/37341 + * gcc.c-torture/compile/pr37341.c: New test. + 2008-10-07 Simon Martin <simartin@users.sourceforge.net> PR c/35437 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37341.c b/gcc/testsuite/gcc.c-torture/compile/pr37341.c new file mode 100644 index 0000000..adbf0c7 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr37341.c @@ -0,0 +1,35 @@ +/* PR rtl-optimization/37341 */ + +short int a; +int b; + +static inline int +f1 (int x, int y) +{ + if (x < 0 || y < 0 || y >= sizeof (int) * 8 || x > (1 >> y)) + return x; +} + +static inline unsigned int +f2 (int x, int y) +{ + if (y <= 0 && x && y < __INT_MAX__ / x) + return x; + return x * y; +} + +int +f3 (void) +{ + return (signed char) 0xb6; +} + +unsigned int +f4 (unsigned int x) +{ + while (1) + { + if ((f2 (f3 (), (f1 (a, b)))) < x) + return 1; + } +} |