From 3af97df7ac22a2392b5b59ed1bd77809c351d2da Mon Sep 17 00:00:00 2001 From: jakub Date: Thu, 21 Jan 2010 00:42:02 +0000 Subject: [PATCH] PR debug/42715 * var-tracking.c (use_type): Choose MO_VAL_SET for REGs set without a cselib val. (count_uses): Accept MO_VAL_SET with no val on stores. (add_stores): Likewise. * gcc.dg/pr42715.c: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@156102 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 ++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/pr42715.c | 59 ++++++++++++++++++++++++++++++++++++++++++ gcc/var-tracking.c | 22 +++++++++++----- 4 files changed, 87 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr42715.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6726e4400fb..4ec8ee68706 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2010-01-20 Alexandre Oliva + + PR debug/42715 + * var-tracking.c (use_type): Choose MO_VAL_SET for REGs set + without a cselib val. + (count_uses): Accept MO_VAL_SET with no val on stores. + (add_stores): Likewise. + 2010-01-20 Jakub Jelinek * var-tracking.c (check_value_val): Add a compile time assertion. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 76d2bc5c163..0fac516223e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-01-20 Alexandre Oliva + + PR debug/42715 + * gcc.dg/pr42715.c: New. + 2010-01-20 Paolo Carlini PR c++/42038 diff --git a/gcc/testsuite/gcc.dg/pr42715.c b/gcc/testsuite/gcc.dg/pr42715.c new file mode 100644 index 00000000000..72bdfc86244 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr42715.c @@ -0,0 +1,59 @@ +/* { dg-do compile { target fpic } } */ +/* { dg-options "-fPIC -g -O2 -w" } */ +/* var-tracking failed to clobber the reg holding v at the asm insn, + so v ended up bound to an intermediate PIC expression. */ + +struct A { unsigned a1; char a2[15]; }; +struct B { long b1; unsigned char b2; long b3; }; +struct C { void *c1; unsigned c2; unsigned c3; }; + +static struct A v1; +struct A *const v2 = &v1; + +static inline +int foo (void) +{ + int *v; + __asm__ __volatile__ ("" : "=r" (v)); + return v[1]; +} + +static void +bar (struct C *x) +{ + if (x->c2 == x->c3 && x->c1) + f1 (foo (), x->c1, x->c3 * sizeof (x->c1[0])); +} + +void +baz (struct B *y) +{ + int i; + const char *j; + char *k; + char x[64]; + for (i = 0; i < sizeof (struct B); i++, y) + { + switch (y->b2) + { + case 0x20: + if (__builtin_strchr (j, '=')) + continue; + } + switch (y->b2) + { + case 0x80: + bar (&x); + f2 (y->b3); + case 0x2e: + case 0x4e: + break; + default: + if (v2->a1) + f2 (y->b2); + } + k[0] = '\0'; + if (v2->a1) + f2 (y->b1); + } +} diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index 5ac3222e140..79e8d560895 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -4426,7 +4426,6 @@ static enum micro_operation_type use_type (rtx loc, struct count_use_info *cui, enum machine_mode *modep) { tree expr; - cselib_val *val; if (cui && cui->sets) { @@ -4447,19 +4446,24 @@ use_type (rtx loc, struct count_use_info *cui, enum machine_mode *modep) return MO_CLOBBER; } - if ((REG_P (loc) || MEM_P (loc)) - && (val = find_use_val (loc, GET_MODE (loc), cui))) + if (REG_P (loc) || MEM_P (loc)) { if (modep) *modep = GET_MODE (loc); if (cui->store_p) { if (REG_P (loc) - || cselib_lookup (XEXP (loc, 0), GET_MODE (loc), 0)) + || (find_use_val (loc, GET_MODE (loc), cui) + && cselib_lookup (XEXP (loc, 0), GET_MODE (loc), 0))) return MO_VAL_SET; } - else if (!cselib_preserved_value_p (val)) - return MO_VAL_USE; + else + { + cselib_val *val = find_use_val (loc, GET_MODE (loc), cui); + + if (val && !cselib_preserved_value_p (val)) + return MO_VAL_USE; + } } } @@ -4580,7 +4584,8 @@ count_uses (rtx *ploc, void *cuip) cselib_preserve_value (val); } else - gcc_assert (mopt == MO_VAL_LOC); + gcc_assert (mopt == MO_VAL_LOC + || (mopt == MO_VAL_SET && cui->store_p)); break; @@ -4968,6 +4973,9 @@ add_stores (rtx loc, const_rtx expr, void *cuip) v = find_use_val (oloc, mode, cui); + if (!v) + goto log_and_return; + resolve = preserve = !cselib_preserved_value_p (v); nloc = replace_expr_with_values (oloc); -- 2.11.0