This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch to stop GCC emitting (subreg (queued ...)) operands
- To: gcc-patches at gcc dot gnu dot org
- Subject: Patch to stop GCC emitting (subreg (queued ...)) operands
- From: Richard Sandiford <r dot sandiford at redhat dot com>
- Date: 10 Jul 2001 10:22:20 +0100
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);
+ }