Richard, This patch fixes PR 55315.
When compiling for the mips target with -O2, function f is folded to 0, while the address of data is not known compile-time: ... int data[4096]; int f (void) { return (((unsigned int) &data[0]) == 0xdeadbea0U); } .... What happens is that expand turns the comparison into the equivalent of: ... (((unsigned int) &data[0]) + (~0xdeadbea0U + 1)) == 0 ... and then nonzero_address_p triggers here during cse: ... case PLUS: if (CONST_INT_P (XEXP (x, 1))) return nonzero_address_p (XEXP (x, 0)); ... and '(((unsigned int) &data[0]) + (~0xdeadbea0U + 1))' is considered a nonzero address, and the comparison evaluates to 0. This example is related to PR 29519, in fact you mention the code pattern expand generates in http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29519#c5. But the patch for that PR does not address this example. This patch prevents nonzero_address_p from assuming that a nonzero address plus a const is a nonzero address. Build and reg-tested on mips. OK for trunk? Thanks, - Tom 2012-11-17 Tom de Vries <t...@codesourcery.com> PR rtl-optimization/55315 * rtlanal.c (nonzero_address_p): Don't assume a nonzero address plus a const is a nonzero address. * gcc.target/mips/pr55315.c: New test.
Index: gcc/rtlanal.c =================================================================== --- gcc/rtlanal.c (revision 193478) +++ gcc/rtlanal.c (working copy) @@ -392,10 +392,8 @@ nonzero_address_p (const_rtx x) return nonzero_address_p (XEXP (x, 0)); case PLUS: - if (CONST_INT_P (XEXP (x, 1))) - return nonzero_address_p (XEXP (x, 0)); /* Handle PIC references. */ - else if (XEXP (x, 0) == pic_offset_table_rtx + if (XEXP (x, 0) == pic_offset_table_rtx && CONSTANT_P (XEXP (x, 1))) return true; return false; Index: gcc/testsuite/gcc.target/mips/pr55315.c =================================================================== --- /dev/null (new file) +++ gcc/testsuite/gcc.target/mips/pr55315.c (revision 0) @@ -0,0 +1,11 @@ +/* { dg-do compile } */ + +int data[4096]; + +int +f (void) +{ + return (((unsigned int) &data[0]) == 0xdeadbea0U); +} + +/* { dg-final { scan-assembler-not "\tmove\t\\\$2,\\\$0" } } */