aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2002-04-17 12:25:31 +0000
committerUlrich Weigand <uweigand@gcc.gnu.org>2002-04-17 12:25:31 +0000
commit7c82a1ed2b4523fb31eb8a33f0728a8cfc7feb6f (patch)
tree2be28a88fbaef5517487dc5570657c0e0f2552f3
parent58db9d1a88e9dc3d704571284af6515c94129fd3 (diff)
downloadgcc-7c82a1ed2b4523fb31eb8a33f0728a8cfc7feb6f.zip
gcc-7c82a1ed2b4523fb31eb8a33f0728a8cfc7feb6f.tar.gz
gcc-7c82a1ed2b4523fb31eb8a33f0728a8cfc7feb6f.tar.bz2
re PR rtl-optimization/6305 (c++ gets ICE in reload_cse_simplify_operands)
PR optimization/6305 * config/s390/s390.c (s390_expand_plus_operand): Use find_replacement to make sure previous reloads are taken into account. Generate better code if one operand is an in-range immediate constant. From-SVN: r52417
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/s390/s390.c26
2 files changed, 25 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2e1d286..558fce4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2002-04-17 Ulrich Weigand <uweigand@de.ibm.com>
+
+ PR optimization/6305
+ * config/s390/s390.c (s390_expand_plus_operand): Use find_replacement
+ to make sure previous reloads are taken into account. Generate
+ better code if one operand is an in-range immediate constant.
+
2002-04-16 Andrew Haley <aph@cambridge.redhat.com>
* doc/install.texi (Building): libgcj requires GNU make.
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index c365f04..131f6ec 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -37,6 +37,7 @@ Boston, MA 02111-1307, USA. */
#include "function.h"
#include "recog.h"
#include "expr.h"
+#include "reload.h"
#include "toplev.h"
#include "basic-block.h"
#include "integrate.h"
@@ -1189,15 +1190,21 @@ s390_expand_plus_operand (target, src, scratch_in)
if (GET_CODE (src) != PLUS || GET_MODE (src) != Pmode)
abort ();
- sum1 = XEXP (src, 0);
- sum2 = XEXP (src, 1);
+ /* Check if any of the two operands is already scheduled
+ for replacement by reload. This can happen e.g. when
+ float registers occur in an address. */
+ sum1 = find_replacement (&XEXP (src, 0));
+ sum2 = find_replacement (&XEXP (src, 1));
/* If one of the two operands is equal to the target,
- make it the first one. */
- if (rtx_equal_p (target, sum2))
+ make it the first one. If one is a constant, make
+ it the second one. */
+ if (rtx_equal_p (target, sum2)
+ || GET_CODE (sum1) == CONST_INT)
{
- sum2 = XEXP (src, 0);
- sum1 = XEXP (src, 1);
+ rtx tem = sum2;
+ sum2 = sum1;
+ sum1 = tem;
}
/* If the first operand is not an address register,
@@ -1210,8 +1217,11 @@ s390_expand_plus_operand (target, src, scratch_in)
/* Likewise for the second operand. However, take
care not to clobber the target if we already used
- it for the first operand. Use the scratch instead. */
- if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
+ it for the first operand. Use the scratch instead.
+ Also, allow an immediate offset if it is in range. */
+ if ((true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
+ && !(GET_CODE (sum2) == CONST_INT
+ && INTVAL (sum2) >= 0 && INTVAL (sum2) < 4096))
{
if (!rtx_equal_p (target, sum1))
{