flow.c (ior_reg_cond): Return NULL if ! add and rtx wasn't optimized.
* flow.c (ior_reg_cond): Return NULL if ! add and rtx wasn't optimized. Return correct value if one of the subexpressions was optimized to 0 resp. 1. Optimize (x | A) | x and (x & A) | x. (and_reg_cond): Similarly. * gcc.c-torture/compile/20011130-2.c: New test. From-SVN: r47602
This commit is contained in:
parent
108b7d3d31
commit
b318748ff4
|
@ -1,3 +1,10 @@
|
|||
2001-12-04 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* flow.c (ior_reg_cond): Return NULL if ! add and rtx wasn't optimized.
|
||||
Return correct value if one of the subexpressions was optimized to
|
||||
0 resp. 1. Optimize (x | A) | x and (x & A) | x.
|
||||
(and_reg_cond): Similarly.
|
||||
|
||||
2001-12-04 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* function.c (assign_parms): Set last_named only for last named
|
||||
|
|
113
gcc/flow.c
113
gcc/flow.c
|
@ -2796,7 +2796,7 @@ flush_reg_cond_reg (pbi, regno)
|
|||
For ior/and, the ADD flag determines whether we want to add the new
|
||||
condition X to the old one unconditionally. If it is zero, we will
|
||||
only return a new expression if X allows us to simplify part of
|
||||
OLD, otherwise we return OLD unchanged to the caller.
|
||||
OLD, otherwise we return NULL to the caller.
|
||||
If ADD is nonzero, we will return a new condition in all cases. The
|
||||
toplevel caller of one of these functions should always pass 1 for
|
||||
ADD. */
|
||||
|
@ -2818,7 +2818,7 @@ ior_reg_cond (old, x, add)
|
|||
&& REGNO (XEXP (x, 0)) == REGNO (XEXP (old, 0)))
|
||||
return old;
|
||||
if (! add)
|
||||
return old;
|
||||
return NULL;
|
||||
return gen_rtx_IOR (0, old, x);
|
||||
}
|
||||
|
||||
|
@ -2827,51 +2827,63 @@ ior_reg_cond (old, x, add)
|
|||
case IOR:
|
||||
op0 = ior_reg_cond (XEXP (old, 0), x, 0);
|
||||
op1 = ior_reg_cond (XEXP (old, 1), x, 0);
|
||||
if (op0 != XEXP (old, 0) || op1 != XEXP (old, 1))
|
||||
if (op0 != NULL || op1 != NULL)
|
||||
{
|
||||
if (op0 == const0_rtx)
|
||||
return op1;
|
||||
return op1 ? op1 : gen_rtx_IOR (0, XEXP (old, 1), x);
|
||||
if (op1 == const0_rtx)
|
||||
return op0;
|
||||
return op0 ? op0 : gen_rtx_IOR (0, XEXP (old, 0), x);
|
||||
if (op0 == const1_rtx || op1 == const1_rtx)
|
||||
return const1_rtx;
|
||||
if (op0 == XEXP (old, 0))
|
||||
op0 = gen_rtx_IOR (0, op0, x);
|
||||
else
|
||||
op1 = gen_rtx_IOR (0, op1, x);
|
||||
if (op0 == NULL)
|
||||
op0 = gen_rtx_IOR (0, XEXP (old, 0), x);
|
||||
else if (rtx_equal_p (x, op0))
|
||||
/* (x | A) | x ~ (x | A). */
|
||||
return old;
|
||||
if (op1 == NULL)
|
||||
op1 = gen_rtx_IOR (0, XEXP (old, 1), x);
|
||||
else if (rtx_equal_p (x, op1))
|
||||
/* (A | x) | x ~ (A | x). */
|
||||
return old;
|
||||
return gen_rtx_IOR (0, op0, op1);
|
||||
}
|
||||
if (! add)
|
||||
return old;
|
||||
return NULL;
|
||||
return gen_rtx_IOR (0, old, x);
|
||||
|
||||
case AND:
|
||||
op0 = ior_reg_cond (XEXP (old, 0), x, 0);
|
||||
op1 = ior_reg_cond (XEXP (old, 1), x, 0);
|
||||
if (op0 != XEXP (old, 0) || op1 != XEXP (old, 1))
|
||||
if (op0 != NULL || op1 != NULL)
|
||||
{
|
||||
if (op0 == const1_rtx)
|
||||
return op1;
|
||||
return op1 ? op1 : gen_rtx_IOR (0, XEXP (old, 1), x);
|
||||
if (op1 == const1_rtx)
|
||||
return op0;
|
||||
return op0 ? op0 : gen_rtx_IOR (0, XEXP (old, 0), x);
|
||||
if (op0 == const0_rtx || op1 == const0_rtx)
|
||||
return const0_rtx;
|
||||
if (op0 == XEXP (old, 0))
|
||||
op0 = gen_rtx_IOR (0, op0, x);
|
||||
else
|
||||
op1 = gen_rtx_IOR (0, op1, x);
|
||||
if (op0 == NULL)
|
||||
op0 = gen_rtx_IOR (0, XEXP (old, 0), x);
|
||||
else if (rtx_equal_p (x, op0))
|
||||
/* (x & A) | x ~ x. */
|
||||
return op0;
|
||||
if (op1 == NULL)
|
||||
op1 = gen_rtx_IOR (0, XEXP (old, 1), x);
|
||||
else if (rtx_equal_p (x, op1))
|
||||
/* (A & x) | x ~ x. */
|
||||
return op1;
|
||||
return gen_rtx_AND (0, op0, op1);
|
||||
}
|
||||
if (! add)
|
||||
return old;
|
||||
return NULL;
|
||||
return gen_rtx_IOR (0, old, x);
|
||||
|
||||
case NOT:
|
||||
op0 = and_reg_cond (XEXP (old, 0), not_reg_cond (x), 0);
|
||||
if (op0 != XEXP (old, 0))
|
||||
if (op0 != NULL)
|
||||
return not_reg_cond (op0);
|
||||
if (! add)
|
||||
return old;
|
||||
return NULL;
|
||||
return gen_rtx_IOR (0, old, x);
|
||||
|
||||
default:
|
||||
|
@ -2921,7 +2933,7 @@ and_reg_cond (old, x, add)
|
|||
&& REGNO (XEXP (x, 0)) == REGNO (XEXP (old, 0)))
|
||||
return old;
|
||||
if (! add)
|
||||
return old;
|
||||
return NULL;
|
||||
return gen_rtx_AND (0, old, x);
|
||||
}
|
||||
|
||||
|
@ -2930,62 +2942,63 @@ and_reg_cond (old, x, add)
|
|||
case IOR:
|
||||
op0 = and_reg_cond (XEXP (old, 0), x, 0);
|
||||
op1 = and_reg_cond (XEXP (old, 1), x, 0);
|
||||
if (op0 != XEXP (old, 0) || op1 != XEXP (old, 1))
|
||||
if (op0 != NULL || op1 != NULL)
|
||||
{
|
||||
if (op0 == const0_rtx)
|
||||
return op1;
|
||||
return op1 ? op1 : gen_rtx_AND (0, XEXP (old, 1), x);
|
||||
if (op1 == const0_rtx)
|
||||
return op0;
|
||||
return op0 ? op0 : gen_rtx_AND (0, XEXP (old, 0), x);
|
||||
if (op0 == const1_rtx || op1 == const1_rtx)
|
||||
return const1_rtx;
|
||||
if (op0 == XEXP (old, 0))
|
||||
op0 = gen_rtx_AND (0, op0, x);
|
||||
else
|
||||
op1 = gen_rtx_AND (0, op1, x);
|
||||
if (op0 == NULL)
|
||||
op0 = gen_rtx_AND (0, XEXP (old, 0), x);
|
||||
else if (rtx_equal_p (x, op0))
|
||||
/* (x | A) & x ~ x. */
|
||||
return op0;
|
||||
if (op1 == NULL)
|
||||
op1 = gen_rtx_AND (0, XEXP (old, 1), x);
|
||||
else if (rtx_equal_p (x, op1))
|
||||
/* (A | x) & x ~ x. */
|
||||
return op1;
|
||||
return gen_rtx_IOR (0, op0, op1);
|
||||
}
|
||||
if (! add)
|
||||
return old;
|
||||
return NULL;
|
||||
return gen_rtx_AND (0, old, x);
|
||||
|
||||
case AND:
|
||||
op0 = and_reg_cond (XEXP (old, 0), x, 0);
|
||||
op1 = and_reg_cond (XEXP (old, 1), x, 0);
|
||||
if (op0 != XEXP (old, 0) || op1 != XEXP (old, 1))
|
||||
if (op0 != NULL || op1 != NULL)
|
||||
{
|
||||
if (op0 == const1_rtx)
|
||||
return op1;
|
||||
return op1 ? op1 : gen_rtx_AND (0, XEXP (old, 1), x);
|
||||
if (op1 == const1_rtx)
|
||||
return op0;
|
||||
return op0 ? op0 : gen_rtx_AND (0, XEXP (old, 0), x);
|
||||
if (op0 == const0_rtx || op1 == const0_rtx)
|
||||
return const0_rtx;
|
||||
if (op0 == XEXP (old, 0))
|
||||
op0 = gen_rtx_AND (0, op0, x);
|
||||
else
|
||||
op1 = gen_rtx_AND (0, op1, x);
|
||||
if (op0 == NULL)
|
||||
op0 = gen_rtx_AND (0, XEXP (old, 0), x);
|
||||
else if (rtx_equal_p (x, op0))
|
||||
/* (x & A) & x ~ (x & A). */
|
||||
return old;
|
||||
if (op1 == NULL)
|
||||
op1 = gen_rtx_AND (0, XEXP (old, 1), x);
|
||||
else if (rtx_equal_p (x, op1))
|
||||
/* (A & x) & x ~ (A & x). */
|
||||
return old;
|
||||
return gen_rtx_AND (0, op0, op1);
|
||||
}
|
||||
if (! add)
|
||||
return old;
|
||||
|
||||
/* If X is identical to one of the existing terms of the AND,
|
||||
then just return what we already have. */
|
||||
/* ??? There really should be some sort of recursive check here in
|
||||
case there are nested ANDs. */
|
||||
if ((GET_CODE (XEXP (old, 0)) == GET_CODE (x)
|
||||
&& REGNO (XEXP (XEXP (old, 0), 0)) == REGNO (XEXP (x, 0)))
|
||||
|| (GET_CODE (XEXP (old, 1)) == GET_CODE (x)
|
||||
&& REGNO (XEXP (XEXP (old, 1), 0)) == REGNO (XEXP (x, 0))))
|
||||
return old;
|
||||
|
||||
return NULL;
|
||||
return gen_rtx_AND (0, old, x);
|
||||
|
||||
case NOT:
|
||||
op0 = ior_reg_cond (XEXP (old, 0), not_reg_cond (x), 0);
|
||||
if (op0 != XEXP (old, 0))
|
||||
if (op0 != NULL)
|
||||
return not_reg_cond (op0);
|
||||
if (! add)
|
||||
return old;
|
||||
return NULL;
|
||||
return gen_rtx_AND (0, old, x);
|
||||
|
||||
default:
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
* g++.dg/other/stdarg1.C: New test.
|
||||
|
||||
* gcc.c-torture/compile/20011130-2.c: New test.
|
||||
|
||||
2001-12-03 Janis Johnson <janis187@us.ibm.com>
|
||||
|
||||
* gcc.c-torture/execute/builtin-prefetch-1.c: New test.
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/* This testcase caused infinite loop in life info computation
|
||||
after if conversion on IA-64. Conditional register dead for
|
||||
pseudo holding sign-extended k was improperly computed,
|
||||
resulting in this pseudo beeing live at start of bb if it was
|
||||
dead at the end and vice versa; as it was a bb which had edge
|
||||
to itself, this resulted in alternative propagating this basic
|
||||
block forever. */
|
||||
|
||||
typedef struct {
|
||||
unsigned char a;
|
||||
unsigned char b;
|
||||
} S0;
|
||||
|
||||
typedef struct {
|
||||
S0 *c;
|
||||
int d;
|
||||
unsigned int e;
|
||||
unsigned char *f[3];
|
||||
void *g;
|
||||
} S1;
|
||||
|
||||
int bar (int, void *);
|
||||
|
||||
int foo (S1 *x, float y)
|
||||
{
|
||||
S0 *h;
|
||||
int i, j, k, l, m;
|
||||
float n, o, p;
|
||||
unsigned char *q, *r[3];
|
||||
|
||||
h = x->c;
|
||||
m = h->a;
|
||||
l = h->b;
|
||||
n = y;
|
||||
o = 0.0;
|
||||
if (x->d == 8)
|
||||
for (j = 0; j < x->e; j++)
|
||||
for (k = 0; k < 3; k++)
|
||||
{
|
||||
n = y;
|
||||
o = 0.0;
|
||||
if (m)
|
||||
q = x->f[k] + x->e - 1 - j;
|
||||
else
|
||||
q = x->f[k] + j;
|
||||
p = (*q - o) * y / (n - o);
|
||||
p = 0.0 > p ? 0.0 : p;
|
||||
p = y < p ? y : p;
|
||||
if (l)
|
||||
p = r[k][(int) p];
|
||||
bar (p, x->g);
|
||||
}
|
||||
return 1;
|
||||
}
|
Loading…
Reference in New Issue