]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/36635 (cc1 segfault from svn 137122)
authorJakub Jelinek <jakub@redhat.com>
Wed, 8 Oct 2008 08:12:25 +0000 (10:12 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 8 Oct 2008 08:12:25 +0000 (10:12 +0200)
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
gcc/cse.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr37341.c [new file with mode: 0644]

index c7144e43b0e54709c24d98e61bb3dedeb60227ec..a4f09c8dd1934e44956b05bf725e03975d234054 100644 (file)
@@ -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
index b911879bf79373bd84de6ac70651704e55a5e190..f4bd77e47009f39bfca52f0fb6d16b44ae29e6a9 100644 (file)
--- 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);
 \f
 
 #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));
index cc7ec163e0714e4726b1258e76317d47cae7029b..031441e40bc15258701325abdc5a11654993302f 100644 (file)
@@ -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 (file)
index 0000000..adbf0c7
--- /dev/null
@@ -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;
+    }
+}