summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2002-11-20 09:52:14 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2002-11-20 09:52:14 +0000
commit19047a6ac7ef32eaa0c2ede0b914d0e30e4cd840 (patch)
tree577d8857ebceccf6f97ebb912ea0316a3e005c83
parent4c286961f9ff0fa9ffa4d232978e6617454a8d39 (diff)
downloadgcc-19047a6ac7ef32eaa0c2ede0b914d0e30e4cd840.tar.gz
* global.c (find_reg): Check HARD_REGNO_NREGS before kicking
out another register. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@59298 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/global.c5
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20021120-1.c58
4 files changed, 72 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 52386836e02..e3ddb43bf83 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2002-11-20 Richard Sandiford <rsandifo@redhat.com>
+
+ * global.c (find_reg): Check HARD_REGNO_NREGS before kicking
+ out another register.
+
2002-11-20 Jakub Jelinek <jakub@redhat.com>
* combine.c (force_to_mode): Only replace with (not Y) if all bits in fuller_mask
diff --git a/gcc/global.c b/gcc/global.c
index dfbe0388d01..471e42e8fd9 100644
--- a/gcc/global.c
+++ b/gcc/global.c
@@ -1192,6 +1192,11 @@ find_reg (num, losers, alt_regs_p, accept_call_clobbered, retrying)
/* Don't use a reg no good for this pseudo. */
&& ! TEST_HARD_REG_BIT (used2, regno)
&& HARD_REGNO_MODE_OK (regno, mode)
+ /* The code below assumes that we need only a single
+ register, but the check of allocno[num].size above
+ was not enough. Sometimes we need more than one
+ register for a single-word value. */
+ && HARD_REGNO_NREGS (regno, mode) == 1
&& (allocno[num].calls_crossed == 0
|| accept_call_clobbered
|| ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a09e7c7235f..1ba905f524a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2002-11-20 Richard Sandiford <rsandifo@redhat.com>
+
+ * gcc.c-torture/execute/20021120-1.c: New test.
+
2002-11-20 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/execute/20021118-3.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20021120-1.c b/gcc/testsuite/gcc.c-torture/execute/20021120-1.c
new file mode 100644
index 00000000000..491d5d6a081
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20021120-1.c
@@ -0,0 +1,58 @@
+/* Macros to emit "L Nxx R" for each octal number xx between 000 and 037. */
+#define OP1(L, N, R, I, J) L N##I##J R
+#define OP2(L, N, R, I) \
+ OP1(L, N, R, 0, I), OP1(L, N, R, 1, I), \
+ OP1(L, N, R, 2, I), OP1(L, N, R, 3, I)
+#define OP(L, N, R) \
+ OP2(L, N, R, 0), OP2(L, N, R, 1), OP2(L, N, R, 2), OP2(L, N, R, 3), \
+ OP2(L, N, R, 4), OP2(L, N, R, 5), OP2(L, N, R, 6), OP2(L, N, R, 7)
+
+/* Declare 32 unique variables with prefix N. */
+#define DECLARE(N) OP (, N,)
+
+/* Copy 32 variables with prefix N from the array at ADDR.
+ Leave ADDR pointing to the end of the array. */
+#define COPYIN(N, ADDR) OP (, N, = *(ADDR++))
+
+/* Likewise, but copy the other way. */
+#define COPYOUT(N, ADDR) OP (*(ADDR++) =, N,)
+
+/* Add the contents of the array at ADDR to 32 variables with prefix N.
+ Leave ADDR pointing to the end of the array. */
+#define ADD(N, ADDR) OP (, N, += *(ADDR++))
+
+volatile double gd[32];
+volatile float gf[32];
+
+void foo (int n)
+{
+ double DECLARE(d);
+ float DECLARE(f);
+ volatile double *pd;
+ volatile float *pf;
+ int i;
+
+ pd = gd; COPYIN (d, pd);
+ for (i = 0; i < n; i++)
+ {
+ pf = gf; COPYIN (f, pf);
+ pd = gd; ADD (d, pd);
+ pd = gd; ADD (d, pd);
+ pd = gd; ADD (d, pd);
+ pf = gf; COPYOUT (f, pf);
+ }
+ pd = gd; COPYOUT (d, pd);
+}
+
+int main ()
+{
+ int i;
+
+ for (i = 0; i < 32; i++)
+ gd[i] = i, gf[i] = i;
+ foo (1);
+ for (i = 0; i < 32; i++)
+ if (gd[i] != i * 4 || gf[i] != i)
+ abort ();
+ exit (0);
+}