From 31e9ebaf7fa9e80817bf1a87f670113a4e02309c Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 8 Oct 2008 10:12:25 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 9 +++++ gcc/cse.c | 19 ++++++---- gcc/testsuite/ChangeLog | 7 ++++ gcc/testsuite/gcc.c-torture/compile/pr37341.c | 35 +++++++++++++++++++ 4 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr37341.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c7144e43b0e..a4f09c8dd19 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2008-10-08 Jakub Jelinek + + 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 * sdbout.c (sdbout_one_type): Treat the value type diff --git a/gcc/cse.c b/gcc/cse.c index b911879bf79..f4bd77e4700 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -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 cc7ec163e07..031441e40bc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2008-10-08 Jakub Jelinek + + PR target/36635 + PR target/37290 + PR rtl-optimization/37341 + * gcc.c-torture/compile/pr37341.c: New test. + 2008-10-07 Simon Martin 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 00000000000..adbf0c7e484 --- /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; + } +}