]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
cse.c (find_comparison_args): Check for cycles of any length.
authorAndrew Jenner <andrew@codesourcery.com>
Thu, 26 Jul 2012 20:51:24 +0000 (20:51 +0000)
committerSandra Loosemore <sandra@gcc.gnu.org>
Thu, 26 Jul 2012 20:51:24 +0000 (16:51 -0400)
2012-07-26  Andrew Jenner  <andrew@codesourcery.com>
    Sandra Loosemore  <sandra@codesourcery.com>

gcc/
* cse.c (find_comparison_args): Check for cycles of any length.

gcc/testsuite/
* gcc.c-torture/compile/pr50380.c: Add code to cause cycle of length 2.

Co-Authored-By: Sandra Loosemore <sandra@codesourcery.com>
From-SVN: r189896

gcc/ChangeLog
gcc/cse.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr50380.c

index ab768846c0b92218c787ef6eb99f7ab7991940c3..0cd287a206a19167fa4c230dc9749867afe80cc4 100644 (file)
@@ -1,3 +1,8 @@
+2012-07-26  Andrew Jenner  <andrew@codesourcery.com>
+           Sandra Loosemore  <sandra@codesourcery.com>
+
+       * cse.c (find_comparison_args): Check for cycles of any length.
+
 2012-07-26  Nick Clifton  <nickc@redhat.com>
 
        * config/mn10300/mn10300.c (REG_SAVE_BYTES): Delete.
index 9a54433c6de818868b91aee12d0e0982eac9f9cc..a8726f3fc3230003bab8b5995ef4d2ad17f868e6 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "df.h"
 #include "dbgcnt.h"
+#include "pointer-set.h"
 
 /* The basic idea of common subexpression elimination is to go
    through the code, keeping a record of expressions that would
@@ -2897,6 +2898,9 @@ find_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
                      enum machine_mode *pmode1, enum machine_mode *pmode2)
 {
   rtx arg1, arg2;
+  struct pointer_set_t *visited = NULL;
+  /* Set nonzero when we find something of interest.  */
+  rtx x = NULL;
 
   arg1 = *parg1, arg2 = *parg2;
 
@@ -2904,11 +2908,18 @@ find_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
 
   while (arg2 == CONST0_RTX (GET_MODE (arg1)))
     {
-      /* Set nonzero when we find something of interest.  */
-      rtx x = 0;
       int reverse_code = 0;
       struct table_elt *p = 0;
 
+      /* Remember state from previous iteration.  */
+      if (x)
+       {
+         if (!visited)
+           visited = pointer_set_create ();
+         pointer_set_insert (visited, x);
+         x = 0;
+       }
+
       /* If arg1 is a COMPARE, extract the comparison arguments from it.
         On machines with CC0, this is the only case that can occur, since
         fold_rtx will return the COMPARE or item being compared with zero
@@ -2985,10 +2996,8 @@ find_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
          if (! exp_equiv_p (p->exp, p->exp, 1, false))
            continue;
 
-         /* If it's the same comparison we're already looking at, skip it.  */
-         if (COMPARISON_P (p->exp)
-             && XEXP (p->exp, 0) == arg1
-             && XEXP (p->exp, 1) == arg2)
+         /* If it's a comparison we've used before, skip it.  */
+         if (visited && pointer_set_contains (visited, p->exp))
            continue;
 
          if (GET_CODE (p->exp) == COMPARE
@@ -3069,6 +3078,8 @@ find_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
   *pmode1 = GET_MODE (arg1), *pmode2 = GET_MODE (arg2);
   *parg1 = fold_rtx (arg1, 0), *parg2 = fold_rtx (arg2, 0);
 
+  if (visited)
+    pointer_set_destroy (visited);
   return code;
 }
 \f
index 805698a5d9faca51ada42b36e06820facac142ff..0773f040fa4813f914ddb511b8461fe25b70d2cb 100644 (file)
@@ -1,3 +1,8 @@
+2012-07-26  Andrew Jenner  <andrew@codesourcery.com>
+           Sandra Loosemore  <sandra@codesourcery.com>
+
+       * gcc.c-torture/compile/pr50380.c: Add code to cause cycle of length 2.
+
 2012-07-26  Tobias Burnus  <burnus@net-b.de>
 
        * gfortran.dg/contiguous_1.f90: Update dg-error.
index ffd044263e54492bdb10871a8e3cb577af85d7df..3f03cbbc31f6e09aa5c3f50a55cb8c0c68a53e38 100644 (file)
@@ -1,12 +1,22 @@
-/* This test used to get stuck in an infinite loop in find_comparison_args
-   when compiling for MIPS at -O2.  */
-
 __attribute__ ((__noreturn__)) extern void fail (void);
 
 char x;
 
+/* This used to get stuck in an infinite loop in find_comparison_args
+   when compiling this function for MIPS at -O2.  */
+
 void foo (const unsigned char y)
 {
    ((void) (__builtin_expect((!! y == y), 1) ? 0 : (fail (), 0)));
    x = ! y;
 }
+
+/* This used to similarly get stuck when compiling for PowerPC at -O2.  */
+
+int foo2 (int arg)
+{
+  if (arg != !arg)
+    fail ();
+  if (arg)
+    fail ();
+}