On Wed, Apr 11, 2012 at 7:21 AM, Richard Sandiford <rdsandif...@googlemail.com> wrote: > "H.J. Lu" <hongjiu...@intel.com> writes: >> Hi, >> >> CSE turns (reg:DI 64) >> >> (insn 6 3 7 2 (set (reg:DI 64) >> (sign_extend:DI (subreg/u:SI (reg/v/f:DI 63 [ addr ]) 0))) x.i:6 122 >> {*extendsidi2_rex64} (nil)) >> >> into (reg/f:DI 64 [ addr ]). But nonzero_bits1 in rtlanal.c has >> >> #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend) >> /* If pointers extend unsigned and this is a pointer in Pmode, say that >> 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 && GET_MODE (x) == Pmode >> && REG_POINTER (x)) >> nonzero &= GET_MODE_MASK (ptr_mode); >> #endif >> >> Setting REG_POINTER with incompatible pointer sign extension is wrong. >> This patch adds a bool parameter to set_reg_attrs_from_value to >> indicate if a register can be marked as a pointer. Does it look OK? >> >> Thanks. >> >> >> H.J. >> --- >> gcc/ >> >> 2012-04-05 H.J. Lu <hongjiu...@intel.com> >> >> PR rtl-optimization/52876 >> * emit-rtl.c (set_reg_attrs_from_value): Add a bool parameter >> to indicate if a register can be a pointer. >> (gen_reg_rtx_and_attrs): Pass true to set_reg_attrs_from_value. >> (set_reg_attrs_for_parm): Likewise. >> >> * emit-rtl.h (set_reg_attrs_from_value): Add a bool parameter. >> >> * reginfo.c (reg_scan_mark_refs): Pass false to >> set_reg_attrs_from_value with incompatible pointer sign >> extension. > > Regardless of how it is currently used, I think gen_reg_rtx_and_attrs > (another caller to set_reg_attrs_from_value) is supposed to be a fairly > general function. So rather than apply a fix specific to regscan, > I think it would be cleaner to redefine set_reg_attrs_from_value as > taking an arbitrary value. The whole while loop: > > while (GET_CODE (src) == SIGN_EXTEND > || GET_CODE (src) == ZERO_EXTEND > || GET_CODE (src) == TRUNCATE > || (GET_CODE (src) == SUBREG && subreg_lowpart_p (src))) > src = XEXP (src, 0); > > would then move to set_reg_attrs_from_value, and the "can be pointer" > thing hidden there. The regscan code would just be: > > if (REG_P (dest) && !REG_ATTRS (dest)) > set_reg_attrs_from_value (dest, src); > > Richard
Here is the updated patch to change set_reg_attrs_from_value to take arbitrary value and check incompatible pointer sign extension. OK for trunk if there are no regressions on Linux/x86-64? Thanks. -- H.J. --- gcc/ 2012-04-10 H.J. Lu <hongjiu...@intel.com> PR rtl-optimization/52876 * emit-rtl.c (set_reg_attrs_from_value): Handle arbitrary value. Don't call mark_reg_pointer for incompatible pointer sign extension. * reginfo.c (reg_scan_mark_refs): Call set_reg_attrs_from_value directly. gcc/testsuite 2012-04-10 H.J. Lu <hongjiu...@intel.com> PR rtl-optimization/52876 * gcc.target/i386/pr52876.c: New.
gcc-pr52876-2.patch
Description: Binary data