This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[testcase] CSE bug
- To: gcc-patches at gcc dot gnu dot org
- Subject: [testcase] CSE bug
- From: Jakub Jelinek <jakub at redhat dot com>
- Date: Mon, 23 Jul 2001 16:35:59 +0200
- Reply-To: Jakub Jelinek <jakub at redhat dot com>
Hi!
Ok to commit testcase below (works at -O0, -O1, does not work at -O2+) at
least on IA-32 (in 2.95.2, 2.96-RH, 3.0 and CVS head)?
It looks like this fails due to the SUBREG logic in cse.c (mention_regs).
p.{x,y} is (subreg:SI (reg:DI 59) {0,4}) and q.{x,y} is
(subreg:SI (reg:DI 60) {0,4}).
Particularly invalidate_skipped_block is run over the q.y = p.y basic block
and thus REG_TICK(60) == REG_IN_TABLE(60) + 1.
Next, mention_regs is called on (subreg:SI (reg/v:DI 60) 0) (= q.x).
The conditions in mention_regs are met and thus only
remove_invalid_subreg_refs is called, not remove_invalid_refs and then
REG_IN_TABLE(60) == REG_TICK(60).
But remove_invalid_subreg_refs(60,0,SImode) invalidates only (subreg:SI (reg:DI 60) 0),
(which in fact was not needed if invalidate_skipped_block recorded somewhere
that only part of the register needs to be invalidated and which one) and
from this point on, (subreg:SI (reg:DI 60) 4) is handled like if nobody
would ever touch it.
Any ideas what's the right way to fix this?
Just kill the REG_IN_TABLE (i) == REG_TICK (i) - 1 trick in mention_regs,
bump REG_TICK once more in invalidate_skipped_set or invalidate so that this
does not trigger or record a bitmap of invalidated subregs (say limited to
64 bits only and working thus with a pseudo's GET_MODE_SIZE () / 64
granularity)?
2001-07-23 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/execute/20010723-1.c: New test.
--- gcc/testsuite/gcc.c-torture/execute/20010723-1.c.jj Fri Feb 16 21:16:31 2001
+++ gcc/testsuite/gcc.c-torture/execute/20010723-1.c Sun Jul 22 21:30:15 2001
@@ -0,0 +1,17 @@
+struct s {
+ int x, y;
+};
+
+int
+main(void)
+{
+ struct s p = {0, 1};
+ struct s q = {0, 2};
+
+ if (q.y > p.y)
+ q.y = p.y;
+ p.y += q.x;
+ if (q.y != 1)
+ abort ();
+ exit (0);
+}
Jakub