]> gcc.gnu.org Git - gcc.git/commitdiff
resource.c (mark_referenced_resources): Handle COND_EXEC.
authorJoern Rennecke <amylaar@gcc.gnu.org>
Fri, 6 Sep 2013 17:37:50 +0000 (18:37 +0100)
committerJoern Rennecke <amylaar@gcc.gnu.org>
Fri, 6 Sep 2013 17:37:50 +0000 (18:37 +0100)
gcc:
* resource.c (mark_referenced_resources): Handle COND_EXEC.
gcc/testsuite:
* gcc.target/arc/cond-set-use.c: New test.

From-SVN: r202344

gcc/ChangeLog
gcc/resource.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arc/cond-set-use.c [new file with mode: 0644]

index 8493ee1424e99a7f120f3de991e552b484aea260..451879429b0236b4e744a323ce6bf455932e753d 100644 (file)
@@ -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.
index 919cffbd0a09c9821a327cca6fc3fc959c8ebb83..367181289df59ce48ce0a21eb2fe3fd6e0e5cc1d 100644 (file)
@@ -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))
index b51e5cef988b0592fac54d7aac1d09ec562b2548..e3b92b2cb20f7b72f0c4a5c3c50d54437c06a1c6 100644 (file)
@@ -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 (file)
index 0000000..aee2725
--- /dev/null
@@ -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;
+}
This page took 0.091395 seconds and 5 git commands to generate.