diff options
author | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-03-25 09:23:47 +0000 |
---|---|---|
committer | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-03-25 09:23:47 +0000 |
commit | 412c63b0282bcdbae22ea0f56af660212f14b817 (patch) | |
tree | 5709052f755bd164f42d4e1e895f136f0fb36fb2 | |
parent | 697e01c840518de6897f50b7392f776c0b9930bb (diff) | |
download | gcc-412c63b0282bcdbae22ea0f56af660212f14b817.tar.gz |
PR rtl-optimization/20249
* cse.c (insert_regs): Do not record equivalence of registers in
different modes.
* gcc.dg/20050325-1.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@97039 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cse.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/20050325-1.c | 19 |
4 files changed, 48 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8fc5365f9bc..3f3252f9897 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-03-25 Zdenek Dvorak <dvorakz@suse.cz> + + PR rtl-optimization/20249 + * cse.c (insert_regs): Do not record equivalence of registers in + different modes. + 2005-03-24 Kazu Hirata <kazu@cs.umass.edu> * emit-rtl.c (reverse_comparison): Remove. diff --git a/gcc/cse.c b/gcc/cse.c index fd5e21ac2ee..4d6f76d9328 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -1234,7 +1234,24 @@ insert_regs (rtx x, struct table_elt *classp, int modified) if (REG_P (classp->exp) && GET_MODE (classp->exp) == GET_MODE (x)) { - make_regs_eqv (regno, REGNO (classp->exp)); + unsigned c_regno = REGNO (classp->exp); + + gcc_assert (REGNO_QTY_VALID_P (c_regno)); + + /* Suppose that 5 is hard reg and 100 and 101 are + pseudos. Consider + + (set (reg:si 100) (reg:si 5)) + (set (reg:si 5) (reg:si 100)) + (set (reg:di 101) (reg:di 5)) + + We would now set REG_QTY (101) = REG_QTY (5), but the + entry for 5 is in SImode. When we use this later in + copy propagation, we get the register in wrong mode. */ + if (qty_table[REG_QTY (c_regno)].mode != GET_MODE (x)) + continue; + + make_regs_eqv (regno, c_regno); return 1; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 65f355a72dc..ce9e6236fbb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-03-25 Zdenek Dvorak <dvorakz@suse.cz> + + PR rtl-optimization/20249 + * gcc.dg/20050325-1.c: New test. + 2005-03-25 Francois-Xavier Coudert <coudert@clipper.ens.fr> PR libfortran/15332 diff --git a/gcc/testsuite/gcc.dg/20050325-1.c b/gcc/testsuite/gcc.dg/20050325-1.c new file mode 100644 index 00000000000..524f9d195c1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20050325-1.c @@ -0,0 +1,19 @@ +/* PR 20249 */ + +/* { dg-do compile } */ +/* dg-options "-O2 -fprofile-arcs" } */ + +extern int *g (int x, void* y); +extern void fg (long long x, int y); + +static void +ff (int y, long long z) +{ + fg (z, 1); +} + +void +f () +{ + g (42, ff); +} |