This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch to stop GCC emitting (subreg (queued ...)) operands



The mips compiler segfaults on the two test cases below.  GCC is emitting
instructions with QUEUED expressions for code like "if (v-- == 1)", where
"v" is a double-word value.

The problem seems to be that the simplify_gen_subreg patch to
operand_subword changed the way it handles QUEUED rtxes.  Before it
would return a null pointer, now it returns (subreg (queued ...)).  So
operand_subword_force now thinks that a QUEUED operand does not need to
be forced into a register.

I'm not sure where best to fix the problem.  Something somewhere has to
check for QUEUED operands, but should it be:

	1) operand_subword_force
	2) operand_subword
	3) simplify_gen_subreg
	4) something else?

In the patch below I went for 3).  It bootstraps on i686-pc-linux-gnu and
make check on mips-elf -mips1 showed no regressions.  I've included two test
cases because they exercise different callers of operand_subword_force
(do_jump_by_parts_greater_rtx and do_jump_by_parts_equality_rtx).

OK to install?

Richard


2001-07-09  Richard Sandiford  <rsandifo@redhat.com>

[gcc/]
	* simplify-rtx.c (simplify_gen_subreg): Return null for QUEUED rtxes.

[gcc/testsuite]
	* gcc.c-torture/compile/20010709-1.c,
	* gcc.c-torture/compile/20010709-2.c: New tests.

Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/simplify-rtx.c,v
retrieving revision 1.64
diff -c -p -d -r1.64 simplify-rtx.c
*** simplify-rtx.c	2001/07/02 15:43:38	1.64
--- simplify-rtx.c	2001/07/10 08:55:11
*************** simplify_gen_subreg (outermode, op, inne
*** 2464,2469 ****
--- 2464,2472 ----
        || byte >= GET_MODE_SIZE (innermode))
      abort ();
  
+   if (GET_CODE (op) == QUEUED)
+     return NULL_RTX;
+ 
    new = simplify_subreg (outermode, op, innermode, byte);
    if (new)
      return new;
*** /dev/null	Thu Aug 24 10:00:32 2000
--- testsuite/gcc.c-torture/compile/20010709-1.c	Mon Jul  9 19:18:53 2001
***************
*** 0 ****
--- 1,11 ----
+ typedef unsigned long long value;
+ 
+ void foo (value *v) {}
+ 
+ void test ()
+ {
+   value v;
+   foo (&v);
+   if (v-- > 0)
+     foo (&v);
+ }
*** /dev/null	Thu Aug 24 10:00:32 2000
--- testsuite/gcc.c-torture/compile/20010709-2.c	Tue Jul 10 09:52:08 2001
***************
*** 0 ****
--- 1,11 ----
+ typedef unsigned long long value;
+ 
+ void foo (value *v) {}
+ 
+ void test ()
+ {
+   value v;
+   foo (&v);
+   if (v-- == 1)
+     foo (&v);
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]