aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2012-07-28 09:34:10 +0930
committerAlan Modra <amodra@gcc.gnu.org>2012-07-28 09:34:10 +0930
commit6ad58e822ee297cd93f9855630a8ab4fc9ad4036 (patch)
tree4c6b02eea54d838e8e7a8d7ea420452873d7015c /gcc
parent5322d07e9c687b4340c4043a11518973e2d6ed9f (diff)
downloadgcc-6ad58e822ee297cd93f9855630a8ab4fc9ad4036.zip
gcc-6ad58e822ee297cd93f9855630a8ab4fc9ad4036.tar.gz
gcc-6ad58e822ee297cd93f9855630a8ab4fc9ad4036.tar.bz2
re PR target/54093 (ICE in in extract_insn, at recog.c:2129)
PR target/54093 * config/rs6000/rs6000.c (rs6000_secondary_reload): Limit 32-bit multi-gpr reload to cases where predicate passes. Do the same for 64-bit multi-gpr reload. From-SVN: r189921
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/rs6000/rs6000.c18
2 files changed, 21 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bbff917..ca2d941 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2012-07-28 Alan Modra <amodra@gmail.com>
+
+ PR target/54093
+ * config/rs6000/rs6000.c (rs6000_secondary_reload): Limit 32-bit
+ multi-gpr reload to cases where predicate passes. Do the same for
+ 64-bit multi-gpr reload.
+
2012-07-27 Nathan Froyd <froydnj@gcc.gnu.org>
* expmed.h (alg_hash, alg_hash_used_p, sdiv_pow2_cheap,
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index ef7d46f..7bb9840 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -13582,8 +13582,11 @@ rs6000_secondary_reload (bool in_p,
&& GET_MODE_SIZE (GET_MODE (x)) >= UNITS_PER_WORD)
{
rtx off = address_offset (XEXP (x, 0));
+ unsigned int extra = GET_MODE_SIZE (GET_MODE (x)) - UNITS_PER_WORD;
- if (off != NULL_RTX && (INTVAL (off) & 3) != 0)
+ if (off != NULL_RTX
+ && (INTVAL (off) & 3) != 0
+ && (unsigned HOST_WIDE_INT) INTVAL (off) + 0x8000 < 0x10000 - extra)
{
if (in_p)
sri->icode = CODE_FOR_reload_di_load;
@@ -13601,10 +13604,17 @@ rs6000_secondary_reload (bool in_p,
&& GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
{
rtx off = address_offset (XEXP (x, 0));
-
+ unsigned int extra = GET_MODE_SIZE (GET_MODE (x)) - UNITS_PER_WORD;
+
+ /* We need a secondary reload only when our legitimate_address_p
+ says the address is good (as otherwise the entire address
+ will be reloaded). So for mode sizes of 8 and 16 this will
+ be when the offset is in the ranges [0x7ffc,0x7fff] and
+ [0x7ff4,0x7ff7] respectively. Note that the address we see
+ here may have been manipulated by legitimize_reload_address. */
if (off != NULL_RTX
- && ((unsigned HOST_WIDE_INT) INTVAL (off) + 0x8000
- >= 0x1000u - (GET_MODE_SIZE (GET_MODE (x)) - UNITS_PER_WORD)))
+ && ((unsigned HOST_WIDE_INT) INTVAL (off) - (0x8000 - extra)
+ < UNITS_PER_WORD))
{
if (in_p)
sri->icode = CODE_FOR_reload_si_load;