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

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
This commit is contained in:
Andrew Jenner 2012-07-26 20:51:24 +00:00 committed by Sandra Loosemore
parent 18a8e9ef96
commit 27ec0502c8
4 changed files with 40 additions and 9 deletions

View 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> 2012-07-26 Nick Clifton <nickc@redhat.com>
* config/mn10300/mn10300.c (REG_SAVE_BYTES): Delete. * config/mn10300/mn10300.c (REG_SAVE_BYTES): Delete.

View File

@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h" #include "tree-pass.h"
#include "df.h" #include "df.h"
#include "dbgcnt.h" #include "dbgcnt.h"
#include "pointer-set.h"
/* The basic idea of common subexpression elimination is to go /* The basic idea of common subexpression elimination is to go
through the code, keeping a record of expressions that would 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) enum machine_mode *pmode1, enum machine_mode *pmode2)
{ {
rtx arg1, arg2; rtx arg1, arg2;
struct pointer_set_t *visited = NULL;
/* Set nonzero when we find something of interest. */
rtx x = NULL;
arg1 = *parg1, arg2 = *parg2; 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))) while (arg2 == CONST0_RTX (GET_MODE (arg1)))
{ {
/* Set nonzero when we find something of interest. */
rtx x = 0;
int reverse_code = 0; int reverse_code = 0;
struct table_elt *p = 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. /* If arg1 is a COMPARE, extract the comparison arguments from it.
On machines with CC0, this is the only case that can occur, since 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 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)) if (! exp_equiv_p (p->exp, p->exp, 1, false))
continue; continue;
/* If it's the same comparison we're already looking at, skip it. */ /* If it's a comparison we've used before, skip it. */
if (COMPARISON_P (p->exp) if (visited && pointer_set_contains (visited, p->exp))
&& XEXP (p->exp, 0) == arg1
&& XEXP (p->exp, 1) == arg2)
continue; continue;
if (GET_CODE (p->exp) == COMPARE 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); *pmode1 = GET_MODE (arg1), *pmode2 = GET_MODE (arg2);
*parg1 = fold_rtx (arg1, 0), *parg2 = fold_rtx (arg2, 0); *parg1 = fold_rtx (arg1, 0), *parg2 = fold_rtx (arg2, 0);
if (visited)
pointer_set_destroy (visited);
return code; return code;
} }

View 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> 2012-07-26 Tobias Burnus <burnus@net-b.de>
* gfortran.dg/contiguous_1.f90: Update dg-error. * gfortran.dg/contiguous_1.f90: Update dg-error.

View 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); __attribute__ ((__noreturn__)) extern void fail (void);
char x; 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 foo (const unsigned char y)
{ {
((void) (__builtin_expect((!! y == y), 1) ? 0 : (fail (), 0))); ((void) (__builtin_expect((!! y == y), 1) ? 0 : (fail (), 0)));
x = ! y; 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 ();
}