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]

[3.3 PATCH] Fix PR optimization/11841


Hi,

This is a regression present on 3.3 branch at -O2 -funroll-loops on x86, 
caused by a bad interaction between GCSE and the (old) unroller.

GCSE does a somewhat awful job in that we end up with only the following 2 
insns referencing pseudo 63:

(insn 118 78 36 2 (nil) (set (reg:SI 63)
        (reg:SI 69)) 38 {*movsi_1} (nil)
    (expr_list:REG_EQUAL (mem/f:SI (symbol_ref:SI ("i")) [3 i+0 S4 A32])
        (nil))

(insn 54 121 98 3 0x401772ec (set (mem/f:SI (symbol_ref:SI ("i")) [3 i+0 S4 
A32])
        (reg:SI 66)) 38 {*movsi_1} (nil)
    (expr_list:REG_EQUAL (plus:SI (reg:SI 63)
            (const_int 1 [0x1]))
        (nil)))


AFAICS, the RTL is correct at this point, albeit clearly pathological.  Then 
the unroller wants to unroll the inner loop and marks pseudo 63 as local to 
the loop, while the REG_EQUAL note is outside the loop.  So pseudo 63 is 
replaced by per-unrolled-loop bivs and we end up with a dangling REG_EQUAL 
note.  It is then rematerialized by CSE2 and all hell breaks loose.

The proposed fix is to teach the unroller to look at notes when deciding 
whether a pseudo is local.  Bootstrapped/regtested on i586-redhat-linux-gnu 
(3.3 branch).  OK for that branch?  Should I put it on the other branches as 
well (GCSE doesn't produce such pathological RTL on 3.4 branch and later 
because store motion was re-enabled, and the old unroller has been 
deprecated).


2004-04-29  Eric Botcazou  <ebotcazou@libertysurf.fr>

	* loop.h (REGNO_LAST_NOTE_LUID): New macro.
	* unroll.c (unroll_loop): Take into account notes when deciding
	whether a pseudo is local to the loop.


2004-04-29  Volker Reichelt <reichelt@igpm.rwth-aachen.de>

	* gcc.dg/loop-4.c: New test.


-- 
Eric Botcazou
/* PR optimization/11841 */
/* Originator: Andrey Panov <panov@canopus.iacp.dvo.ru> */
/* Reduced testcase by Volker Reichelt <reichelt@igpm.rwth-aachen.de> */

/* Verify that the (old) loop unroller doesn't wrongly mark a pseudo
   referenced in a note as local.  */

/* { dg-do run } */
/* { dg-options "-O2 -funroll-loops" } */

int *a;

int main()
{
  double d[6];
  int i, j;

  for (i=0; i<4; ++i)
    for (j=0; j<3; ++j)
      d[i+j] = 0;

  a = &i;

  return 0;
}
Index: loop.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/loop.h,v
retrieving revision 1.65.2.1
diff -u -p -r1.65.2.1 loop.h
--- loop.h	27 Sep 2003 17:23:17 -0000	1.65.2.1
+++ loop.h	29 Apr 2004 07:32:14 -0000
@@ -51,6 +51,7 @@ Software Foundation, 59 Temple Place - S
 
 #define REGNO_FIRST_LUID(REGNO) uid_luid[REGNO_FIRST_UID (REGNO)]
 #define REGNO_LAST_LUID(REGNO) uid_luid[REGNO_LAST_UID (REGNO)]
+#define REGNO_LAST_NOTE_LUID(REGNO) uid_luid[REGNO_LAST_NOTE_UID (REGNO)]
 
 
 /* A "basic induction variable" or biv is a pseudo reg that is set
Index: unroll.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/unroll.c,v
retrieving revision 1.184.2.8
diff -u -p -r1.184.2.8 unroll.c
--- unroll.c	13 Mar 2004 01:19:05 -0000	1.184.2.8
+++ unroll.c	29 Apr 2004 07:32:28 -0000
@@ -794,8 +794,8 @@ unroll_loop (loop, insn_count, strength_
       for (r = FIRST_PSEUDO_REGISTER; r < max_reg_before_loop; ++r)
 	if (REGNO_FIRST_UID (r) > 0 && REGNO_FIRST_UID (r) < max_uid_for_loop
 	    && REGNO_FIRST_LUID (r) >= copy_start_luid
-	    && REGNO_LAST_UID (r) > 0 && REGNO_LAST_UID (r) < max_uid_for_loop
-	    && REGNO_LAST_LUID (r) <= copy_end_luid)
+	    && REGNO_LAST_NOTE_UID (r) > 0 && REGNO_LAST_NOTE_UID (r) < max_uid_for_loop
+	    && REGNO_LAST_NOTE_LUID (r) <= copy_end_luid)
 	  {
 	    /* However, we must also check for loop-carried dependencies.
 	       If the value the pseudo has at the end of iteration X is

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