summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2005-03-25 09:23:47 +0000
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2005-03-25 09:23:47 +0000
commit412c63b0282bcdbae22ea0f56af660212f14b817 (patch)
tree5709052f755bd164f42d4e1e895f136f0fb36fb2
parent697e01c840518de6897f50b7392f776c0b9930bb (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cse.c19
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/20050325-1.c19
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);
+}