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]
Other format: [Raw text]

[PATCH] Fix PR middle-end/14470


Hi,

This is the "does-not-work-as-intended" PR for 

  d = t[d]++;

for which GCC emits the equivalent of

  d = t[d];
  t[d]++;

at -O, a "regression" from the 3.0.4 release.


I use double-quotes because, according to the comments in the audit trail, it 
is not clear whether this is a defect in the compiler or not.

Assuming the former conclusion, the problem comes from store_expr, more 
specifically from the code that is responsible for generating the move to 
the original target when expand_expr has returned a temporary.  In the 
present case, the temporary is the QUEUE for the post-increment, which 
references the original target.  The code emits the move (insn 37) before 
unqueuing, which clobbers the original target referenced in the 
not-yet-emitted p-i:

(insn 36 31 37 (set (reg:SI 77)
        (mem/s/j:SI (plus:SI (plus:SI (mult:SI (reg/v:SI 74 [ d ])
                        (const_int 4 [0x4]))
                    (reg/f:SI 54 virtual-stack-vars))
                (const_int -496 [0xfffffe10])) [0 t S4 A32])) -1 (nil)
    (nil))

(insn 37 36 33 (set (reg/v:SI 74 [ d ])
        (reg:SI 77)) -1 (nil)
    (nil))

(insn 33 37 34 (set (reg:SI 76)
        (mem/s/j:SI (plus:SI (plus:SI (mult:SI (reg/v:SI 74 [ d ])
                        (const_int 4 [0x4]))
                    (reg/f:SI 54 virtual-stack-vars))
                (const_int -496 [0xfffffe10])) [0 t S4 A32])) -1 (nil)
    (nil))

(insn 34 33 35 (parallel [
            (set (reg:SI 75)
                (plus:SI (reg:SI 76)
                    (const_int 1 [0x1])))
            (clobber (reg:CC 17 flags))
        ]) -1 (nil)
    (nil))

(insn 35 34 39 (set (mem/s/j:SI (plus:SI (plus:SI (mult:SI (reg/v:SI 74 [ d 
])
                        (const_int 4 [0x4]))
                    (reg/f:SI 54 virtual-stack-vars))
                (const_int -496 [0xfffffe10])) [0 t S4 A32])
        (reg:SI 75)) -1 (nil)
    (nil))


I think that, since both the source and the target of the store have been 
expanded at this point, it is safe to emit the queue.  But I would not bet 
many euros on that.

Bootstrapped/regtested on i586-redhat-linux (3.4 branch).  OK for mainline 
and 3.4 branch?


2004-03-09  Eric Botcazou  <ebotcazou@libertysurf.fr>

        PR middle-end/14470
	* expr.c (store_expr): Call emit_queue before generating the move
	from the temporary to the original target.  Protect the temporary
	from emit_queue.


2004-03-09  Eric Botcazou  <ebotcazou@libertysurf.fr>

        * gcc.c-torture/execute/20040309-1.c: New test.


-- 
Eric Botcazou
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.615.4.7
diff -u -p -r1.615.4.7 expr.c
--- expr.c	8 Mar 2004 06:58:26 -0000	1.615.4.7
+++ expr.c	8 Mar 2004 12:56:35 -0000
@@ -4249,7 +4249,9 @@ store_expr (tree exp, rtx target, int wa
 	 bit-initialized.  */
       && expr_size (exp) != const0_rtx)
     {
+      emit_queue();
       target = protect_from_queue (target, 1);
+      temp = protect_from_queue (temp, 0);
       if (GET_MODE (temp) != GET_MODE (target)
 	  && GET_MODE (temp) != VOIDmode)
 	{
/* PR middle-end/14470 */
/* Origin: Lodewijk Voge <lvoge@cs.vu.nl> */

extern void abort(void);

int main()
{
  int t[1025] = { 1024 }, d;

  d = 0;
  d = t[d]++;
  if (t[0] != 1025)
    abort();
  return 0;
}

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