diff options
author | Jakub Jelinek <jakub@redhat.com> | 2001-12-04 10:33:17 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2001-12-04 10:33:17 +0100 |
commit | b318748ff4b6a9256695a3e768d4a951dd4b8ca6 (patch) | |
tree | f4cbf2a19a8962de46bab2e668b5770fcd6f9668 /gcc | |
parent | 108b7d3d316599861369de7c7f9bfaef915c7bd3 (diff) | |
download | gcc-b318748ff4b6a9256695a3e768d4a951dd4b8ca6.zip gcc-b318748ff4b6a9256695a3e768d4a951dd4b8ca6.tar.gz gcc-b318748ff4b6a9256695a3e768d4a951dd4b8ca6.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/flow.c | 113 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/20011130-2.c | 54 |
4 files changed, 126 insertions, 50 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dff736e..fff9d98 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 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 argument. @@ -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: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4c7036f..76f673f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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. diff --git a/gcc/testsuite/gcc.c-torture/compile/20011130-2.c b/gcc/testsuite/gcc.c-torture/compile/20011130-2.c new file mode 100644 index 0000000..6439527 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20011130-2.c @@ -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; +} |