Check for incompatible pointer sign extension

gcc/

	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

	PR rtl-optimization/52876
	* gcc.target/i386/pr52876.c: New.

From-SVN: r186351
This commit is contained in:
H.J. Lu 2012-04-11 19:31:45 +00:00 committed by H.J. Lu
parent d3ea1dbdb2
commit de6f3f7ab8
5 changed files with 59 additions and 13 deletions

View File

@ -1,3 +1,13 @@
2012-04-11 H.J. Lu <hongjiu.lu@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.
2012-04-11 Bernd Schmidt <bernds@codesourcery.com>
* fold-const.c (fold_unary_loc): Use GET_MODE_PRECISION for

View File

@ -970,6 +970,22 @@ void
set_reg_attrs_from_value (rtx reg, rtx x)
{
int offset;
bool can_be_reg_pointer = true;
/* Don't call mark_reg_pointer for incompatible pointer sign
extension. */
while (GET_CODE (x) == SIGN_EXTEND
|| GET_CODE (x) == ZERO_EXTEND
|| GET_CODE (x) == TRUNCATE
|| (GET_CODE (x) == SUBREG && subreg_lowpart_p (x)))
{
#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
if ((GET_CODE (x) == SIGN_EXTEND && POINTERS_EXTEND_UNSIGNED)
|| (GET_CODE (x) != SIGN_EXTEND && ! POINTERS_EXTEND_UNSIGNED))
can_be_reg_pointer = false;
#endif
x = XEXP (x, 0);
}
/* Hard registers can be reused for multiple purposes within the same
function, so setting REG_ATTRS, REG_POINTER and REG_POINTER_ALIGN
@ -983,14 +999,14 @@ set_reg_attrs_from_value (rtx reg, rtx x)
if (MEM_OFFSET_KNOWN_P (x))
REG_ATTRS (reg) = get_reg_attrs (MEM_EXPR (x),
MEM_OFFSET (x) + offset);
if (MEM_POINTER (x))
if (can_be_reg_pointer && MEM_POINTER (x))
mark_reg_pointer (reg, 0);
}
else if (REG_P (x))
{
if (REG_ATTRS (x))
update_reg_offset (reg, x, offset);
if (REG_POINTER (x))
if (can_be_reg_pointer && REG_POINTER (x))
mark_reg_pointer (reg, REGNO_POINTER_ALIGN (REGNO (x)));
}
}

View File

@ -1222,17 +1222,7 @@ reg_scan_mark_refs (rtx x, rtx insn)
/* If this is setting a register from a register or from a simple
conversion of a register, propagate REG_EXPR. */
if (REG_P (dest) && !REG_ATTRS (dest))
{
rtx src = SET_SRC (x);
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);
set_reg_attrs_from_value (dest, src);
}
set_reg_attrs_from_value (dest, SET_SRC (x));
/* ... fall through ... */

View File

@ -1,3 +1,8 @@
2012-04-11 H.J. Lu <hongjiu.lu@intel.com>
PR rtl-optimization/52876
* gcc.target/i386/pr52876.c: New.
2012-04-11 Bernd Schmidt <bernds@codesourcery.com>
* gcc.dg/c99-const-expr-9.c (old_offsetof): Insert a cast to

View File

@ -0,0 +1,25 @@
/* { dg-do run { target { x32 } } } */
/* { dg-options "-O2 -mx32 -maddress-mode=long" } */
extern void abort (void);
long long li;
long long
__attribute__ ((noinline))
testfunc (void* addr)
{
li = (long long)(int)addr;
li &= 0xffffffff;
return li;
}
int main (void)
{
volatile long long rv_test;
rv_test = testfunc((void*)0x87651234);
if (rv_test != 0x87651234ULL)
abort ();
return 0;
}