This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[3.3 PATCH] Fix PR optimization/11841
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 29 Apr 2004 09:45:00 +0200
- Subject: [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