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 for protect_from_queue bug


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


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