[backport from gcc-4.7/trunk, fixes MIPS gcc-loops bug PR50380 ] gcc/ 2011-12-19 Sandra Loosemore Tom de Vries PR rtl-opt/50380 * cse.c (find_comparison_args): Detect fixed point and bail early. gcc/testsuite/ 2011-12-19 Sandra Loosemore Tom de Vries PR rtl-opt/50380 * gcc.c-torture/compile/pr50380.c: New testcase. --- gcc-4.6.2/gcc/cse.c.~1~ 2011-06-14 17:01:10.000000000 +0200 +++ gcc-4.6.2/gcc/cse.c 2011-12-24 16:08:54.000000000 +0100 @@ -3054,6 +3054,12 @@ find_comparison_args (enum rtx_code code 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 --- gcc-4.6.2/gcc/testsuite/gcc.c-torture/compile/pr50380.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.6.2/gcc/testsuite/gcc.c-torture/compile/pr50380.c 2011-12-24 16:08:54.000000000 +0100 @@ -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; +}