On Feb  4, 2015, Alexandre Oliva <lxol...@fsfla.org> wrote:

> Nevermind, I got the build stuck at vp9_cx_iface on parkes, and on the
> cross compiler at a faster build machine.  It gets stuck in the first
> common subexpression elimination optimization pass (cse1) in a partial
> clone of function validate_config.  It fails even with -O2.

> I found out that compiling with -fno-cse-follow-jumps in addition to -O3
> or -O2 makes it finish compilation very quickly, presumably at some loss
> of optimization.  You might want to use that for now, at least until I
> debug the compiler it properly.  That might take a while, though.

For tiny values of a while, fortunately ;-)

This is GCC bug 50380:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50380

The patch associated with that PR is enough to get vp9_cx_iface to
compile, however, there was a subsequent patch that complemented the fix
so as to catch additional similar situations that would loop endlessly.

I enclose both patches below.  Building gcc with both ought to fix the
problem and make libvpx (and hopefully iceweasel) buildable.

2011-12-19  Sandra Loosemore  <san...@codesourcery.com>

From: sandra <sandra@138bc75d-0d04-0410-961f-82ee72b054a4>

Tom de Vries <t...@codesourcery.com>

	PR rtl-opt/50380

	gcc/
	* cse.c (find_comparison_args): Detect fixed point and
	bail early.

	gcc/testsuite/
	* gcc.c-torture/compile/pr50380.c: New testcase.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182498 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/cse.c                                     |    6 ++++++
 gcc/testsuite/gcc.c-torture/compile/pr50380.c |   12 ++++++++++++
 2 files changed, 18 insertions(+)
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr50380.c

diff --git a/gcc/cse.c b/gcc/cse.c
index 078977f..7609114 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -3054,6 +3054,12 @@ 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)
+	    continue;
+
 	  if (GET_CODE (p->exp) == COMPARE
 	      /* Another possibility is that this machine has a compare insn
 		 that includes the comparison code.  In that case, ARG1 would
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr50380.c b/gcc/testsuite/gcc.c-torture/compile/pr50380.c
new file mode 100644
index 0000000..ffd0442
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr50380.c
@@ -0,0 +1,12 @@
+/* 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;
+
+void foo (const unsigned char y)
+{
+   ((void) (__builtin_expect((!! y == y), 1) ? 0 : (fail (), 0)));
+   x = ! y;
+}
2012-07-26  Andrew Jenner  <and...@codesourcery.com>

From: sandra <sandra@138bc75d-0d04-0410-961f-82ee72b054a4>

Sandra Loosemore  <san...@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.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@189896 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/cse.c                                     |   23 +++++++++++++++++------
 gcc/testsuite/gcc.c-torture/compile/pr50380.c |   16 +++++++++++++---
 2 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/gcc/cse.c b/gcc/cse.c
index 7609114..8b32350 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -45,6 +45,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
@@ -2966,6 +2967,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;
 
@@ -2973,11 +2977,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
@@ -3054,10 +3065,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
@@ -3146,6 +3155,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;
 }
 
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr50380.c b/gcc/testsuite/gcc.c-torture/compile/pr50380.c
index ffd0442..3f03cbb 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr50380.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr50380.c
@@ -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 ();
+}

-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer
_______________________________________________
gNewSense-dev mailing list
gNewSense-dev@nongnu.org
https://lists.nongnu.org/mailman/listinfo/gnewsense-dev

Reply via email to