aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hongjiu.lu@intel.com>2012-04-11 19:31:45 +0000
committerH.J. Lu <hjl@gcc.gnu.org>2012-04-11 12:31:45 -0700
commitde6f3f7ab8d0ffd3a01bd045a90317d8404c9591 (patch)
treea22fa5858f537ac51f83ae37d539fb42a9c209ab
parentd3ea1dbdb267abe428d444f586af1fc724556898 (diff)
downloadgcc-de6f3f7ab8d0ffd3a01bd045a90317d8404c9591.zip
gcc-de6f3f7ab8d0ffd3a01bd045a90317d8404c9591.tar.gz
gcc-de6f3f7ab8d0ffd3a01bd045a90317d8404c9591.tar.bz2
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
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/emit-rtl.c20
-rw-r--r--gcc/reginfo.c12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr52876.c25
5 files changed, 59 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9ea90db..f3fcfca 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 8d7d441..9da585c 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -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)));
}
}
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index 6353126..f3a08f5 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -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 ... */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7a764f4..1a22457 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/gcc.target/i386/pr52876.c b/gcc/testsuite/gcc.target/i386/pr52876.c
new file mode 100644
index 0000000..6d5e47a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr52876.c
@@ -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;
+}