From 3748bd9e22eafbd213c7d268d0a00b8b35faf743 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 20 Nov 2002 09:52:14 +0000 Subject: [PATCH] global.c (find_reg): Check HARD_REGNO_NREGS before kicking out another register. * global.c (find_reg): Check HARD_REGNO_NREGS before kicking out another register. From-SVN: r59298 --- gcc/ChangeLog | 5 ++ gcc/global.c | 5 ++ gcc/testsuite/ChangeLog | 4 ++ .../gcc.c-torture/execute/20021120-1.c | 58 +++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 gcc/testsuite/gcc.c-torture/execute/20021120-1.c 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 + + * global.c (find_reg): Check HARD_REGNO_NREGS before kicking + out another register. + 2002-11-20 Jakub Jelinek * 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 + + * gcc.c-torture/execute/20021120-1.c: New test. + 2002-11-20 Jakub Jelinek * 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); +} -- 2.30.2