aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2009-08-18 13:42:07 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2009-08-18 13:42:07 +0200
commitf3252b3c18e688f43df708d0003f0b6e0f89cc17 (patch)
tree5241028b107c2cf85d8f0660f93ee0ecbcd300fc
parent68a315304bedd286bcb99966ec7b3a3d21c0ccc0 (diff)
downloadgcc-f3252b3c18e688f43df708d0003f0b6e0f89cc17.zip
gcc-f3252b3c18e688f43df708d0003f0b6e0f89cc17.tar.gz
gcc-f3252b3c18e688f43df708d0003f0b6e0f89cc17.tar.bz2
re PR target/40971 (ICE in memory_address)
PR target/40971 * config/rs6000/rs6000.c (rs6000_legitimize_address): For [DT][FDI]mode ensure the offset isn't 4/8/12 bytes below 0x8000. * gcc.dg/pr40971.c: New test. From-SVN: r150869
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/config/rs6000/rs6000.c31
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr40971.c23
4 files changed, 61 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e684f7a..adbf70f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -3,6 +3,10 @@
* bb-reorder.c (fix_up_fall_thru_edges): Only call invert_jump
on jumps.
+ PR target/40971
+ * config/rs6000/rs6000.c (rs6000_legitimize_address): For
+ [DT][FDI]mode ensure the offset isn't 4/8/12 bytes below 0x8000.
+
2009-08-17 DJ Delorie <dj@redhat.com>
* config/m32c/m32c.md (UNS_FSETB, UNS_FREIT): New.
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 8c0feb5..b4a0592 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -4857,6 +4857,8 @@ static rtx
rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
enum machine_mode mode)
{
+ unsigned int extra = 0;
+
if (!reg_offset_addressing_ok_p (mode))
{
if (virtual_stack_registers_memory_p (x))
@@ -4881,10 +4883,33 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
if (model != 0)
return rs6000_legitimize_tls_address (x, model);
}
+
+ switch (mode)
+ {
+ case DFmode:
+ case DDmode:
+ extra = 4;
+ break;
+ case DImode:
+ if (!TARGET_POWERPC64)
+ extra = 4;
+ break;
+ case TFmode:
+ case TDmode:
+ extra = 12;
+ break;
+ case TImode:
+ extra = TARGET_POWERPC64 ? 8 : 12;
+ break;
+ default:
+ break;
+ }
+
if (GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == REG
&& GET_CODE (XEXP (x, 1)) == CONST_INT
- && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000
+ && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
+ >= 0x10000 - extra)
&& !((TARGET_POWERPC64
&& (mode == DImode || mode == TImode)
&& (INTVAL (XEXP (x, 1)) & 3) != 0)
@@ -4896,10 +4921,12 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
HOST_WIDE_INT high_int, low_int;
rtx sum;
low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
+ if (low_int >= 0x8000 - extra)
+ low_int = 0;
high_int = INTVAL (XEXP (x, 1)) - low_int;
sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
GEN_INT (high_int)), 0);
- return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
+ return plus_constant (sum, low_int);
}
else if (GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == REG
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8a05c84..e1c0885 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-08-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/40971
+ * gcc.dg/pr40971.c: New test.
+
2008-08-17 Paul Thomas <pault@gcc.gnu.org>
PR fortran/41062
diff --git a/gcc/testsuite/gcc.dg/pr40971.c b/gcc/testsuite/gcc.dg/pr40971.c
new file mode 100644
index 0000000..31dfd5e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr40971.c
@@ -0,0 +1,23 @@
+/* PR target/40971 */
+/* { dg-do compile } */
+/* { dg-options "-O -fstack-protector -fno-strict-aliasing" } */
+/* { dg-require-effective-target fstack_protector } */
+
+extern void bar (char *);
+
+void
+foo (int f, long a)
+{
+ {
+ char d[32768];
+ bar (d);
+ }
+ double b = f;
+ while (a)
+ {
+ char c[sizeof (double)];
+ __builtin_memcpy (c, &b, sizeof (c));
+ if (*(double *) c != 2.0)
+ break;
+ }
+}