Hi, I just don't see how nonzero_bits1 can assume if pointers extend unsigned and this is an addition or subtraction to a pointer in Pmode, all the bits bove ptr_mode are known to be zero. We never run into it before x32 since x32 is the first such target.
This patch deletes it. OK to install the nonzero_bits1 part for trunk? Thanks. H.J. --- diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32 index 564e123..9bbb05b 100644 --- a/gcc/ChangeLog.x32 +++ b/gcc/ChangeLog.x32 @@ -1,3 +1,9 @@ +2011-06-22 H.J. Lu <hongjiu...@intel.com> + + PR rtl-optimization/49504 + * rtlanal.c (nonzero_bits1): Properly handle addition or + subtraction a pointer in Pmode if pointers extend unsigned. + 2011-06-15 H.J. Lu <hongjiu...@intel.com> PR middle-end/48016 diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index b52957d..e5c045d 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -4134,20 +4134,6 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x, if (result_low > 0) nonzero &= ~(((unsigned HOST_WIDE_INT) 1 << result_low) - 1); - -#ifdef POINTERS_EXTEND_UNSIGNED - /* If pointers extend unsigned and this is an addition or subtraction - to a pointer in Pmode, all the bits above ptr_mode are known to be - zero. */ - /* As we do not know which address space the pointer is refering to, - we can do this only if the target does not support different pointer - or address modes depending on the address space. */ - if (target_default_pointer_address_modes_p () - && POINTERS_EXTEND_UNSIGNED > 0 && GET_MODE (x) == Pmode - && (code == PLUS || code == MINUS) - && REG_P (XEXP (x, 0)) && REG_POINTER (XEXP (x, 0))) - nonzero &= GET_MODE_MASK (ptr_mode); -#endif } break; diff --git a/gcc/testsuite/ChangeLog.x32 b/gcc/testsuite/ChangeLog.x32 index ab8dd76..6581a45 100644 --- a/gcc/testsuite/ChangeLog.x32 +++ b/gcc/testsuite/ChangeLog.x32 @@ -1,3 +1,8 @@ +2011-06-22 H.J. Lu <hongjiu...@intel.com> + + PR rtl-optimization/49504 + * gcc.target/i386/pr49504.c: New. + 2011-06-15 H.J. Lu <hongjiu...@intel.com> * gcc.dg/pr44194-1.c: Also allow x32. diff --git a/gcc/testsuite/gcc.target/i386/pr49504.c b/gcc/testsuite/gcc.target/i386/pr49504.c new file mode 100644 index 0000000..9128196 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr49504.c @@ -0,0 +1,18 @@ +/* PR target/49504 */ +/* { dg-do run { target { x32 } } } */ +/* { dg-options "-O" } */ + +unsigned long long +foo (const void* p, unsigned long long q) +{ + unsigned long long a = (((unsigned long long) ((unsigned long) p)) + q) >> 32; + return a; +} + +int +main () +{ + if (foo ((const void*) 0x100, 0x100000000ULL) == 0) + __builtin_abort (); + return 0; +}