diff mbox

PR rtl-optimization/47925: deleting trivially live instructions

Message ID g41v2py7ns.fsf@linaro.org
State Accepted
Headers show

Commit Message

Richard Sandiford March 2, 2011, 1:27 p.m. UTC
Richard Guenther <richard.guenther@gmail.com> writes:
> On Tue, Mar 1, 2011 at 12:29 AM, Eric Botcazou <ebotcazou@adacore.com> wrote:
>>> The bug showed up as a wrong-code regression in a modified version of Qt,
>>> but I haven't yet found a testcase that fails with 4.6 but passes with
>>> an older GCC.  Is the patch OK now regardless, or should it wait for 4.7?
>>
>> Fine for 4.6 with me, but I think you also need an ack from a RM.
>
> Ok with me.

Thanks.  Here's what I installed, with the comment update.

Richard


gcc/
	PR rtl-optimization/47925
	* cse.c (count_reg_usage): Don't ignore the SET_DEST of instructions
	with side effects.  Remove the more-specific check for volatile asms.

gcc/testsuite/
	PR rtl-optimization/47925
	* gcc.c-torture/execute/pr47925.c: New test.
diff mbox

Patch

Index: gcc/cse.c
===================================================================
--- gcc/cse.c	2010-10-18 10:53:30.000000000 +0100
+++ gcc/cse.c	2011-03-01 08:57:25.000000000 +0000
@@ -6575,8 +6575,9 @@  check_for_label_ref (rtx *rtl, void *dat
    Don't count a usage of DEST, which is the SET_DEST of a SET which
    contains X in its SET_SRC.  This is because such a SET does not
    modify the liveness of DEST.
-   DEST is set to pc_rtx for a trapping insn, which means that we must count
-   uses of a SET_DEST regardless because the insn can't be deleted here.  */
+   DEST is set to pc_rtx for a trapping insn, or for an insn with side effects.
+   We must then count uses of a SET_DEST regardless, because the insn can't be
+   deleted here.  */
 
 static void
 count_reg_usage (rtx x, int *counts, rtx dest, int incr)
@@ -6629,9 +6630,10 @@  count_reg_usage (rtx x, int *counts, rtx
     case CALL_INSN:
     case INSN:
     case JUMP_INSN:
-      /* We expect dest to be NULL_RTX here.  If the insn may trap, mark
-         this fact by setting DEST to pc_rtx.  */
-      if (insn_could_throw_p (x))
+      /* We expect dest to be NULL_RTX here.  If the insn may trap,
+	 or if it cannot be deleted due to side-effects, mark this fact
+	 by setting DEST to pc_rtx.  */
+      if (insn_could_throw_p (x) || side_effects_p (PATTERN (x)))
 	dest = pc_rtx;
       if (code == CALL_INSN)
 	count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, dest, incr);
@@ -6671,10 +6673,6 @@  count_reg_usage (rtx x, int *counts, rtx
       return;
 
     case ASM_OPERANDS:
-      /* If the asm is volatile, then this insn cannot be deleted,
-	 and so the inputs *must* be live.  */
-      if (MEM_VOLATILE_P (x))
-	dest = NULL_RTX;
       /* Iterate over just the inputs, not the constraints as well.  */
       for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
 	count_reg_usage (ASM_OPERANDS_INPUT (x, i), counts, dest, incr);
Index: gcc/testsuite/gcc.c-torture/execute/pr47925.c
===================================================================
--- /dev/null	2011-02-21 12:47:04.267827113 +0000
+++ gcc/testsuite/gcc.c-torture/execute/pr47925.c	2011-02-28 16:05:17.000000000 +0000
@@ -0,0 +1,24 @@ 
+struct s { volatile struct s *next; };
+
+void __attribute__((noinline))
+bar (int ignored, int n)
+{
+  asm volatile ("");
+}
+
+int __attribute__((noinline))
+foo (volatile struct s *ptr, int n)
+{
+  int i;
+
+  bar (0, n);
+  for (i = 0; i < n; i++)
+    ptr = ptr->next;
+}
+
+int main (void)
+{
+  volatile struct s rec = { &rec };
+  foo (&rec, 10);
+  return 0;
+}