diff options
author | Joern Rennecke <amylaar@gcc.gnu.org> | 2013-09-06 18:37:50 +0100 |
---|---|---|
committer | Joern Rennecke <amylaar@gcc.gnu.org> | 2013-09-06 18:37:50 +0100 |
commit | 3a001aff33dee19c0e93dddd4a31b67b044db267 (patch) | |
tree | 203b948fdf9aeb277ad7db4a330532f3c0fce32f /gcc | |
parent | c42091c1b505de009cea3420537a5453d81d0165 (diff) | |
download | gcc-3a001aff33dee19c0e93dddd4a31b67b044db267.zip gcc-3a001aff33dee19c0e93dddd4a31b67b044db267.tar.gz gcc-3a001aff33dee19c0e93dddd4a31b67b044db267.tar.bz2 |
resource.c (mark_referenced_resources): Handle COND_EXEC.
gcc:
* resource.c (mark_referenced_resources): Handle COND_EXEC.
gcc/testsuite:
* gcc.target/arc/cond-set-use.c: New test.
From-SVN: r202344
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/resource.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arc/cond-set-use.c | 128 |
4 files changed, 147 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8493ee1..4518794 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,8 @@ -2013-09-06 Claudiu Zissulescu <claziss@synopsys.com> +2013-09-06 Joern Rennecke <joern.rennecke@embecosm.com> + + * resource.c (mark_referenced_resources): Handle COND_EXEC. + +2013-09-06 Claudiu Zissulescu <claziss@synopsys.com> * resource.c (mark_target_live_regs): Compute resources taking into account if a call is predicated or not. diff --git a/gcc/resource.c b/gcc/resource.c index 919cffb..3671812 100644 --- a/gcc/resource.c +++ b/gcc/resource.c @@ -374,6 +374,16 @@ mark_referenced_resources (rtx x, struct resources *res, case INSN: case JUMP_INSN: + if (GET_CODE (PATTERN (x)) == COND_EXEC) + /* In addition to the usual references, also consider all outputs + as referenced, to compensate for mark_set_resources treating + them as killed. This is similar to ZERO_EXTRACT / STRICT_LOW_PART + handling, execpt that we got a partial incidence instead of a partial + width. */ + mark_set_resources (x, res, 0, + include_delayed_effects + ? MARK_SRC_DEST_CALL : MARK_SRC_DEST); + #ifdef INSN_REFERENCES_ARE_DELAYED if (! include_delayed_effects && INSN_REFERENCES_ARE_DELAYED (x)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b51e5ce..e3b92b2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2013-09-06 Joern Rennecke <joern.rennecke@embecosm.com> + + * gcc.target/arc/cond-set-use.c: New test. + 2013-09-06 Eric Botcazou <ebotcazou@adacore.com> * gnat.dg/stack_usage2.adb: New test. diff --git a/gcc/testsuite/gcc.target/arc/cond-set-use.c b/gcc/testsuite/gcc.target/arc/cond-set-use.c new file mode 100644 index 0000000..aee2725 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/cond-set-use.c @@ -0,0 +1,128 @@ +/* { dg-do run } */ +/* { dg-options "-Os" } */ + +/* Based on gethostbyname_r, + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB + * + * Extraction / wrapping as test by + * Joern Rennecke <joern.rennecke@embecosm.com> + * Copyright (C) 2013 Free Software Foundation, Inc. + */ + +typedef unsigned size_t; +typedef int ssize_t; +typedef unsigned uint32_t; +struct resolv_answer { + char *dotted; + int atype; + int aclass; + int ttl; + int rdlength; + const unsigned char *rdata; + int rdoffset; + char* buf; + size_t buflen; + size_t add_count; +}; +struct hostent +{ + char *h_name; + char **h_aliases; + int h_addrtype; + int h_length; + char **h_addr_list; +}; + +int *__attribute__ ((noinline,weak)) nop (void * p) { return p; }; +void __attribute__ ((noinline,weak)) seta (struct resolv_answer * p) +{ p->atype = 1;} + +int ghostbyname_r( + struct hostent *result_buf, + char *buf, + size_t buflen, + struct hostent **result, + int *h_errnop) +{ + char **addr_list; + char **alias; + char *alias0; + int i0; + struct resolv_answer a; + int i; + + *result = ((void *)0); + + *h_errnop = -1; + + if ((ssize_t)buflen <= 5) + return 34; + + alias = (char **)buf; + addr_list = (char **)buf; + + /* This got turned into branch with conditional move in delay slot. */ + if ((ssize_t)buflen < 256) + return 34; + + + { + if (!nop(&i0)) { + result_buf->h_aliases = alias; + result_buf->h_addrtype = 2; + result_buf->h_length = 4; + result_buf->h_addr_list = addr_list; + *result = result_buf; + *h_errnop = 0; + return 0; + } + } + + + seta (&a); + + if (a.atype == 1) { + + int need_bytes = sizeof(addr_list[0]) * (a.add_count + 1 + 1); + + int ips_len = a.add_count * a.rdlength; + + buflen -= (need_bytes + ips_len); + if ((ssize_t)buflen < 0) { + i = 34; + goto free_and_ret; + } + + result_buf->h_addrtype = 2; + *result = result_buf; + *h_errnop = 0; + i = 0; + goto free_and_ret; + } + + /* For cse, the 1 was is loaded into a call-saved register; + the load was hoisted into a delay slot before the conditional load, + clobbering result_buf, which (conditionally) lived in the same + call-saved register, because mark_referenced_resources considered the + destination of the COND_EXEC only clobbered, but not used. */ + *h_errnop = 1; + *nop(&i0) = 1; + i = 2; + + free_and_ret: + nop (&i0); + return i; +} + +int +main () +{ + struct hostent buf, *res; + int i; + char c; + ghostbyname_r (&buf, &c, 1024, &res, &i); + ghostbyname_r (&buf, 0, 1024, &res, &i); + return 0; +} |