From patchwork Fri Sep 6 10:22:13 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joern Rennecke X-Patchwork-Id: 273138 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "www.sourceware.org", Issuer "StartCom Class 1 Primary Intermediate Server CA" (not verified)) by ozlabs.org (Postfix) with ESMTPS id EA1862C00FC for ; Fri, 6 Sep 2013 20:22:22 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:to:cc:subject:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=e/RltsQ7sw9dpByh dz+v1YEj0DzaFeGNrKB9aZl+zta9dJ8qiYnC+j3Tyd0D+aILk7UwuNhLWlZm01pE FHqktO1mLcBFGkTkb1sIdseXqLZzQMebuGUVlDEOvq1FQ9ypLDmmAcdCUSlCwpKd GRQqQLJl8BaqY6pHg8g+GPMVNHw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:to:cc:subject:mime-version:content-type :content-transfer-encoding; s=default; bh=y4O1hss0w9fkcTLAtenV83 RNhiY=; b=xNC9yoMpop8Z4AwJMubrq6mJlGwAE2g3T9ZDZ4EiLsJ/EpRdI7eDVe JHsFC1ronli+gSPkDbkU8GK8OiK6et0Vg+0SLfDR/fLt4Si42QnxSpwntCWqHV5v B8uOyGQpyc28y/xQnytMdAn0eErR3/y5wkQ+LZInZk8kWmirhgGKY= Received: (qmail 31567 invoked by alias); 6 Sep 2013 10:22:16 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 31558 invoked by uid 89); 6 Sep 2013 10:22:16 -0000 Received: from c62.cesmail.net (HELO c62.cesmail.net) (216.154.195.54) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Fri, 06 Sep 2013 10:22:16 +0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.2 required=5.0 tests=AWL, BAYES_50, FSL_HELO_NON_FQDN_1, RDNS_NONE autolearn=no version=3.3.2 X-HELO: c62.cesmail.net Received: from unknown (HELO epsilon2) ([192.168.1.60]) by c62.cesmail.net with ESMTP; 06 Sep 2013 06:22:13 -0400 Received: from cust213-dsl91-135-11.idnet.net (cust213-dsl91-135-11.idnet.net [91.135.11.213]) by webmail.spamcop.net (Horde MIME library) with HTTP; Fri, 06 Sep 2013 06:22:13 -0400 Message-ID: <20130906062213.pkczc5rlwkgwwocg-nzlynne@webmail.spamcop.net> Date: Fri, 06 Sep 2013 06:22:13 -0400 From: Joern Rennecke To: gcc-patches@gcc.gnu.org Cc: Jeff Law Subject: RFA: Fix mark_referenced_resources to handle COND_EXEC MIME-Version: 1.0 User-Agent: Internet Messaging Program (IMP) H3 (4.1.4) We found that gethostbyname_r from uClibc got miscompiled for ARC because reorg thought a COND_EXEC unconditionally kills all the conditionally set registers. Making it think that the registers are not killed is no good either, because then we would miss anti-dependencies. So, short of adding some complex predicate-tracing across all paths, it is best to consider the result registers to be used before set. bootstrapped / regtested on i686-pc-linux-gnu. Well, that's not a particular relevant port since it doesn't combine delay_slots with COND_EXEC, but then, only ARC does, and it's still waiting for review. And an arc-linux-uclibc system can't boot properly without this patch being applied to the compiler, and you have to boot the system before doing a compiler bootstrap... and the later is also a bit uncommon for embedded targets. This is also the reason I placed the test into gcc.target; in principle the test could also live in gcc.dg, but it would only be relevant to ARC. OK to apply? gcc: 2013-04-30 Joern Rennecke * resource.c (mark_referenced_resources): Handle COND_EXEC. gcc/testsuite: 2013-08-31 Joern Rennecke * gcc.target/arc/cond-set-use.c: 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 + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB + * + * Extraction / wrapping as test by + * Joern Rennecke + * 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; +} Index: resource.c =================================================================== --- resource.c (revision 202295) +++ resource.c (working copy) @@ -374,6 +374,16 @@ mark_referenced_resources (rtx x, struct 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))