From patchwork Thu Apr 25 21:56:30 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 239600 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 "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 2A8CA2C0122 for ; Fri, 26 Apr 2013 07:56:48 +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:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; q=dns; s=default; b=c8PTVfpkyqr4QRxw0oY5dR2BbD6WW XhA2SgUSfVeqTfEGPChWXYpaaSFuYB1LGAn09F1acl6l3/CK2gwoS6WQMQfmNpLv dZc7HTyn2ty9QX6f5ylyJ5vcrHeADrpIbOVkuLiVqIqUIorceh1n8kqQN+Q8MHBg pcGct+Pn4CwEls= 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:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; s=default; bh=ZswfE+V0F6R5dIs0IYIWppMcuQs=; b=v// bPL2JSBE9PTMECz4mfaEnnKB8Xf6U0q0XTteYXDjzz1/P4qDvbS7f7RavdHhcycB QNAFbParin0ixymxlKJ0BbjqpzQHyPgvg5JKMaLEa8HZj9DHjOu1eoWfEx8061Hk Wp36JVQx4Lo/dE9hM+oDb6th2nUFL4cZ/7S45yvk= Received: (qmail 29166 invoked by alias); 25 Apr 2013 21:56:41 -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 29155 invoked by uid 89); 25 Apr 2013 21:56:41 -0000 X-Spam-SWARE-Status: No, score=-6.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS, TW_CG, TW_CP autolearn=no version=3.3.1 Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Thu, 25 Apr 2013 21:56:41 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r3PLubS2027487 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 25 Apr 2013 17:56:38 -0400 Received: from zalov.cz (vpn-61-36.rdu2.redhat.com [10.10.61.36]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r3PLuZSg014263 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 25 Apr 2013 17:56:36 -0400 Received: from zalov.cz (localhost [127.0.0.1]) by zalov.cz (8.14.5/8.14.5) with ESMTP id r3PLuYGU010635; Thu, 25 Apr 2013 23:56:34 +0200 Received: (from jakub@localhost) by zalov.cz (8.14.5/8.14.5/Submit) id r3PLuWiE010634; Thu, 25 Apr 2013 23:56:32 +0200 Date: Thu, 25 Apr 2013 23:56:30 +0200 From: Jakub Jelinek To: gcc-patches@gcc.gnu.org Cc: Bernd Schmidt Subject: [committed] Fix recgprop bug with ms_abi -> sysv memcpy call (PR rtl-optimization/57003) Message-ID: <20130425215630.GK28963@tucnak.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Hi! This patch fixes a bug where a ms_abi -> sysv call to memcpy is miscompiled. In this case, registers %rdi and %rsi aren't call clobbered in the ms_abi, and are in sysv ABI, thus they aren't in the regs_invalidated_by_call regset, but are instead represented by clobber in the pattern of the CALL_INSN. copyprop_hardreg_forward_1 kills clobbered values early, but when seeing a SET in CALL_INSN_FUNCTION_USAGE, it adds a new equivalence for it (%rdi vs. %rax in this case). When the first argument register is call clobbered, normally the regs_invalidated_by_call handling would again kill the equivalence, and if it isn't clobbered, then the equivalence should stay, but in this case we need to clobber it because of the CLOBBERs. Fixed thusly, acked by Bernd in the PR, bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk and 4.8 branch. 2013-04-25 Jakub Jelinek PR rtl-optimization/57003 * regcprop.c (copyprop_hardreg_forward_1): If ksvd.ignore_set_reg, call note_stores with kill_clobbered_value callback again after killing regs_invalidated_by_call. * gcc.target/i386/pr57003.c: New test. Jakub --- gcc/regcprop.c.jj 2013-01-11 09:03:17.000000000 +0100 +++ gcc/regcprop.c 2013-04-25 11:43:38.472315617 +0200 @@ -1015,6 +1015,13 @@ copyprop_hardreg_forward_1 (basic_block EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, 0, regno, hrsi) if (regno < set_regno || regno >= set_regno + set_nregs) kill_value_regno (regno, 1, vd); + + /* If SET was seen in CALL_INSN_FUNCTION_USAGE, and SET_SRC + of the SET isn't in regs_invalidated_by_call hard reg set, + but instead among CLOBBERs on the CALL_INSN, we could wrongly + assume the value in it is still live. */ + if (ksvd.ignore_set_reg) + note_stores (PATTERN (insn), kill_clobbered_value, vd); } /* Notice stores. */ --- gcc/testsuite/gcc.target/i386/pr57003.c.jj 2013-04-25 11:44:37.312994815 +0200 +++ gcc/testsuite/gcc.target/i386/pr57003.c 2013-04-25 11:44:32.851008197 +0200 @@ -0,0 +1,54 @@ +/* PR rtl-optimization/57003 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +#define N 2001 +unsigned short *b, *c, *d; + +__attribute__ ((noinline, noclone)) unsigned +bar (void) +{ + asm volatile ("" : : : "memory"); + return N; +} + +__attribute__ ((noinline, noclone)) unsigned short * +baz (unsigned long x) +{ + if (x != N * sizeof (unsigned short) + 20) + __builtin_abort (); + asm volatile ("" : : : "memory"); + return d; +} + +__attribute__ ((ms_abi, noinline, noclone)) +foo (void) +{ + unsigned d; + unsigned short *e; + if ((d = bar ())) + { + e = baz (d * sizeof (unsigned short) + 20); + __builtin_memcpy (e, b, d * sizeof (unsigned short)); + c = e; + } +} + +int +main () +{ + unsigned short a[2 * N]; + int i; + for (i = 0; i < 2 * N; i++) + a[i] = i + 1; + b = a; + d = a + N; + asm volatile ("" : : : "memory"); + foo (); + for (i = 0; i < N; i++) + if (a[i] != i + 1 || a[i + N] != i + 1) + __builtin_abort (); + if (c != a + N) + __builtin_abort (); + return 0; +}