diff options
author | Jakub Jelinek <jakub@redhat.com> | 2009-08-18 13:42:07 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2009-08-18 13:42:07 +0200 |
commit | f3252b3c18e688f43df708d0003f0b6e0f89cc17 (patch) | |
tree | 5241028b107c2cf85d8f0660f93ee0ecbcd300fc | |
parent | 68a315304bedd286bcb99966ec7b3a3d21c0ccc0 (diff) | |
download | gcc-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/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 31 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr40971.c | 23 |
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; + } +} |