This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[4.1] Fix PR rtl-optimization/30931
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 27 Feb 2007 21:24:55 +0100
- Subject: [4.1] Fix PR rtl-optimization/30931
It's again a regression from the 3.x series present on the 4.1 branch and due
to the old loop optimizer, a variant of PR rtl-optimization/30787.
The GIV associated with the second p[i].first
for (i=0; i < 2; i++)
while (p[i].first && p[i].done)
p[i].first = 0;
is correctly detected as not "always executed", but it is nevertheless reduced
because it is first combined with the "always executed" first p[i].first.
Fixed by disallowing combining for GIVs that are not "always executed".
Bootstrapped/regtested on x86_64-suse-linux and applied to 4.1 branch.
2007-02-27 Eric Botcazou <ebotcazou@libertysurf.fr>
PR rtl-optimization/30931
* loop.c (combine_givs_p): Return false if either GIV is not
always executed.
2007-02-27 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.c-torture/execute/20070227-1.c: New test.
--
Eric Botcazou
Index: loop.c
===================================================================
--- loop.c (revision 122251)
+++ loop.c (working copy)
@@ -8700,6 +8700,10 @@ combine_givs_p (struct induction *g1, st
{
rtx comb, ret;
+ /* We cannot combine givs that are not always in sync. */
+ if (!g1->always_executed || !g2->always_executed)
+ return NULL_RTX;
+
/* With the introduction of ext dependent givs, we must care for modes.
G2 must not use a wider mode than G1. */
if (GET_MODE_SIZE (g1->mode) < GET_MODE_SIZE (g2->mode))
@@ -8708,6 +8712,7 @@ combine_givs_p (struct induction *g1, st
ret = comb = express_from (g1, g2);
if (comb == NULL_RTX)
return NULL_RTX;
+
if (g1->mode != g2->mode)
ret = gen_lowpart (g2->mode, comb);
@@ -8718,9 +8723,7 @@ combine_givs_p (struct induction *g1, st
combination to be the other way round. */
if (comb == g1->dest_reg
&& (g1->giv_type == DEST_REG || g2->giv_type == DEST_ADDR))
- {
- return ret;
- }
+ return ret;
/* If G2 can be expressed as a function of G1 and that function is valid
as an address and no more expensive than using a register for G2,
/* PR rtl-optimization/30931 */
/* Testcase by Peter Bergner <bergner@gcc.gnu.org> */
struct s
{
int first;
int done;
};
void bug (struct s *p)
{
int i;
for (i=0; i < 2; i++)
{
while (p[i].first && p[i].done)
p[i].first = 0;
}
}
int main (void)
{
struct s array[2];
array[0].first = 1;
array[0].done = 1;
array[1].first = 0;
array[1].done = 0;
bug (array);
return 0;
}