I am testing the following patch to fix PR51730. Richard.
2012-01-02 Richard Guenther <rguent...@suse.de> PR middle-end/51730 * fold-const.c (fold_comparison): Properly canonicalize tree offset and HOST_WIDE_INT bit position. * gcc.dg/fold-compare-6.c: New testcase. Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 182784) +++ gcc/fold-const.c (working copy) @@ -8886,6 +8886,14 @@ fold_comparison (location_t loc, enum tr indirect_base0 = true; } offset0 = TREE_OPERAND (arg0, 1); + if (host_integerp (offset0, 0) + && ((HOST_WIDE_INT) (TREE_INT_CST_LOW (offset0) * BITS_PER_UNIT) + / BITS_PER_UNIT + == (HOST_WIDE_INT) TREE_INT_CST_LOW (offset0))) + { + bitpos0 = TREE_INT_CST_LOW (offset0) * BITS_PER_UNIT; + offset0 = NULL_TREE; + } } base1 = arg1; @@ -8909,6 +8917,14 @@ fold_comparison (location_t loc, enum tr indirect_base1 = true; } offset1 = TREE_OPERAND (arg1, 1); + if (host_integerp (offset1, 0) + && ((HOST_WIDE_INT) (TREE_INT_CST_LOW (offset1) * BITS_PER_UNIT) + / BITS_PER_UNIT + == (HOST_WIDE_INT) TREE_INT_CST_LOW (offset1))) + { + bitpos1 = TREE_INT_CST_LOW (offset1) * BITS_PER_UNIT; + offset1 = NULL_TREE; + } } /* A local variable can never be pointed to by Index: gcc/testsuite/gcc.dg/fold-compare-6.c =================================================================== --- gcc/testsuite/gcc.dg/fold-compare-6.c (revision 0) +++ gcc/testsuite/gcc.dg/fold-compare-6.c (revision 0) @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-tree-original" } */ + +char digs[] = "0123456789"; +int foo (void) +{ + int xlcbug = 1 / (&(digs + 5)[-2 + (_Bool) 1] == &digs[4] ? 1 : -1); + return xlcbug; +} + +/* { dg-final { scan-tree-dump "xlcbug = 1;" "original" } } */ +/* { dg-final { cleanup-tree-dump "original" } } */