This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Problem with recent addressof change
- To: egcs-patches at cygnus dot com
- Subject: Problem with recent addressof change
- From: Bernd Schmidt <crux at Pool dot Informatik dot RWTH-Aachen dot DE>
- Date: Fri, 2 Oct 1998 14:47:12 +0200 (MET DST)
- cc: rth at cygnus dot com
Recently, purge_addressof_1 has been changed to fix a bug where the compiler
would change a (MEM:mode1 (ADDRESSOF:mode2 xxx)) to a SUBREG if mode1 was
different from mode2. However, the new code causes problems with
gcc.c-torture/compile/930217-1.c on i586-linux.
I have not debugged the problem fully, but it seems that purge_addressof
creates rtl that causes combine to create a giant (probably circular) rtl
structure, and the compiler does not terminate.
The expression that leads to this is of the form
(MEM:HI (ADDRESSOF:SI (REG:SF)))
Currently, this will be changed to (SUBREG:HI (REG:SF)) by purge_addressof.
I must admit that I don't understand all the subreg "magic" in the compiler,
but I have strong doubts whether such an expression is legal. At least I've
never seen something like this before.
The patch below makes purge_addressof_1 avoid such expressions. That fixed
the failure, but it doesn't explain why combine made a circular rtl structure
out of it.
Bernd
* function.c (purge_addressof_1): Don't make MODE_INT subregs of
MODE_FLOAT regs.
Index: ../../gcs/gcc/function.c
===================================================================
RCS file: /usr/local/cvs/gcs/gcc/function.c,v
retrieving revision 1.1.1.37
diff -u -p -r1.1.1.37 function.c
--- function.c 1998/10/01 14:39:17 1.1.1.37
+++ function.c 1998/10/01 21:03:21
@@ -2873,8 +2873,11 @@ purge_addressof_1 (loc, insn, force, sto
size_sub = GET_MODE_BITSIZE (GET_MODE (sub));
/* Don't even consider working with paradoxical subregs,
- or the moral equivalent seen here. */
- if (size_x < size_sub)
+ or the moral equivalent seen here.
+ Don't even consider making MODE_INT subregs of MODE_FLOAT
+ regs. */
+ if (size_x < size_sub
+ && GET_MODE_CLASS (GET_MODE (sub)) == MODE_INT)
{
/* Do a bitfield insertion to mirror what would happen
in memory. */