This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch for protect_from_queue bug
- To: <gcc-patches at gcc dot gnu dot org>
- Subject: Patch for protect_from_queue bug
- From: Bernd Schmidt <bernds at redhat dot com>
- Date: Thu, 17 May 2001 14:58:03 +0100 (BST)
- cc: <mark at codesourcery dot com>
There's a problem in 2.95 and in the mainline with protect_from_queue.
One bug report is c++/2818; there was another but I can't find it anymore.
What happens is that we have a QUEUED rtx and call protect_from_queue.
This function notices that we haven't incremented the register yet, and
just returns the reg. Then, we call emit_queue before using the value,
and the register incorrectly gets incremented before the use.
This is fixed by the patch below. This also fixes another bug I noticed
while debugging this: if we call protect_from_queue for an ADDR_EXPR, we
really don't want it to return a REG if we gave it a MEM; we want the
original address.
(A different solution might be to rip out all the queueing nonsense. It
slightly improved code last time I checked, but it may not be worth all
the headaches.)
I'm checking this in on the 2.95 branch and in the mainline (after the
bootstrap on i686-linux completes). Mark, I'll leave the decision whether
to put it into 3.0 up to you.
Bernd
* expr.c (protect_from_queue): Protect against subsequent calls to
emit_queue.
Index: expr.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/expr.c,v
retrieving revision 1.144.4.10
diff -u -p -r1.144.4.10 expr.c
--- expr.c 2001/03/19 13:37:17 1.144.4.10
+++ expr.c 2001/05/17 12:50:23
@@ -450,6 +450,9 @@ protect_from_queue (x, modify)
QUEUED_INSN (y));
return temp;
}
+ /* Copy the address into a pseudo, so that the returned value
+ remains correct across calls to emit_queue. */
+ XEXP (new, 0) = copy_to_reg (XEXP (new, 0));
return new;
}
/* Otherwise, recursively protect the subexpressions of all
@@ -476,9 +479,11 @@ protect_from_queue (x, modify)
}
return x;
}
- /* If the increment has not happened, use the variable itself. */
+ /* If the increment has not happened, use the variable itself. Copy it
+ into a new pseudo so that the value remains correct across calls to
+ emit_queue. */
if (QUEUED_INSN (x) == 0)
- return QUEUED_VAR (x);
+ return copy_to_reg (QUEUED_VAR (x));
/* If the increment has happened and a pre-increment copy exists,
use that copy. */
if (QUEUED_COPY (x) != 0)
@@ -8077,7 +8082,9 @@ expand_expr (exp, target, tmode, modifie
if (ignore)
return op0;
- op0 = protect_from_queue (op0, 0);
+ /* Pass 1 for MODIFY, so that protect_from_queue doesn't get
+ clever and returns a REG when given a MEM. */
+ op0 = protect_from_queue (op0, 1);
/* We would like the object in memory. If it is a constant,
we can have it be statically allocated into memory. For