This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR optimization/10876
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 20 May 2003 19:56:09 +0200
- Subject: [PATCH] Fix PR optimization/10876
Hi,
This is a regression from GCC 3.2.3 on 32-bit Sparc, present on mainline and
3.3 branch, which triggers when compiling aRts/KDE 3.1.2 at -O2.
The compiler segfaults in unroll.c:calculate_giv_inc() after a series of
events, which can be traced back to an assumption made by the function:
general induction variables are incremented with a PLUS (after strength
reduction).
Now, on Sparc, the addsi3 expander may emit a MINUS under certain
circumstances, which confuses calculate_giv_inc().
Bootstrapped/regtested on sparc-sun-solaris2.9 (c,c++,objc,f77 3.3 branch).
Ok for 3.3 branch and mainline?
--
Eric Botcazou
2003-05-20 Eric Botcazou <ebotcazou@libertysurf.fr>
PR optimization/10876
* unroll.c (calculate_giv_inc): Handle givs that are
incremented with a MINUS.
2003-05-20 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.c-torture/compile/20030520-1.c: New test.
Index: gcc/unroll.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/unroll.c,v
retrieving revision 1.184.2.2
diff -u -r1.184.2.2 unroll.c
--- gcc/unroll.c 25 Mar 2003 20:23:07 -0000 1.184.2.2
+++ gcc/unroll.c 20 May 2003 10:27:31 -0000
@@ -1588,14 +1588,16 @@
retry:
/* Verify that we have an increment insn here. First check for a plus
- as the set source. */
- if (GET_CODE (SET_SRC (pattern)) != PLUS)
+ or a minus as the set source. */
+ if (GET_CODE (SET_SRC (pattern)) != PLUS
+ && GET_CODE (SET_SRC (pattern)) != MINUS)
{
/* SR sometimes computes the new giv value in a temp, then copies it
to the new_reg. */
src_insn = PREV_INSN (src_insn);
pattern = single_set (src_insn);
- if (GET_CODE (SET_SRC (pattern)) != PLUS)
+ if (GET_CODE (SET_SRC (pattern)) != PLUS
+ && GET_CODE (SET_SRC (pattern)) != MINUS)
abort ();
/* The last insn emitted is not needed, so delete it to avoid confusing
@@ -1603,10 +1605,21 @@
delete_related_insns (get_last_insn ());
}
- /* Verify that we have a constant as the second operand of the plus. */
+ /* Verify that we have a constant as the second operand. */
increment = XEXP (SET_SRC (pattern), 1);
- if (GET_CODE (increment) != CONST_INT)
+ if (GET_CODE (increment) == CONST_INT)
{
+ /* The Sparc port may emit a minus under certain circumstances when
+ the addsi3 pattern is invoked. */
+ if (GET_CODE (SET_SRC (pattern)) == MINUS)
+ increment = GEN_INT (-INTVAL (increment));
+ }
+ else
+ {
+ /* We don't handle minus in this branch. */
+ if (GET_CODE (SET_SRC (pattern)) == MINUS)
+ abort();
+
/* SR sometimes puts the constant in a register, especially if it is
too big to be an add immed operand. */
increment = find_last_value (increment, &src_insn, NULL_RTX, 0);
/* PR optimization/10876 */
/* Contributed by Christian Ehrhardt */
/* Verify that the loop optimizer takes into
account an oddity of the Sparc port. */
void f(void)
{
unsigned int butterfly, block, offset;
double *Z;
for (block = 0; block < 512; block += 512) {
double T1re, T2re;
offset = butterfly + block;
T1re += T2re;
T2re = Z[offset] + T1re;
}
}