From patchwork Fri Jun 28 15:09:13 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Meissner X-Patchwork-Id: 255418 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 479822C0095 for ; Sat, 29 Jun 2013 01:09:29 +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:subject:message-id:mime-version:content-type; q=dns; s= default; b=eStyppRUttJE3F1ZHY/31NgbTzXp/je+cqVscJZobkvdnDgngyueB Fv6zQjbiNaqunvs81L9wIIFSZ0W9hXKiKHPFDY7iGOmcvp8h3UZ+MN+6MdYGaNh2 29bf51jsyXkzqrS2C2qVj5vB8i23nV2lUcOh0HtD4Z6dsKVfTqeX8M= 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:subject:message-id:mime-version:content-type; s= default; bh=NHc55KtLkPUcQRHTwMmoSPd2sIM=; b=FimK4LWTThV/HYnzz9o1 60Fuqrl9jhAbGTzZHtrJtNEOZ0x+vTHeGm4Df3Il5t4AJDWIZhsDmmqZpstO/vpu bau0IC8YBejHiCWDVLs7oSqbvyS8QhIaSn56EFA/exUfMSL0JfDKqpKHvlL6tpjv ZnO81foTPjxiP4o5gS6cO5Y= Received: (qmail 26311 invoked by alias); 28 Jun 2013 15:09:22 -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 26298 invoked by uid 89); 28 Jun 2013 15:09:22 -0000 X-Spam-SWARE-Status: No, score=-3.5 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL autolearn=ham version=3.3.1 Received: from e8.ny.us.ibm.com (HELO e8.ny.us.ibm.com) (32.97.182.138) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Fri, 28 Jun 2013 15:09:20 +0000 Received: from /spool/local by e8.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 28 Jun 2013 16:09:19 +0100 Received: from d01dlp03.pok.ibm.com (9.56.250.168) by e8.ny.us.ibm.com (192.168.1.108) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 28 Jun 2013 16:09:16 +0100 Received: from d01relay06.pok.ibm.com (d01relay06.pok.ibm.com [9.56.227.116]) by d01dlp03.pok.ibm.com (Postfix) with ESMTP id 961AAC90068 for ; Fri, 28 Jun 2013 11:09:14 -0400 (EDT) Received: from d01av03.pok.ibm.com (d01av03.pok.ibm.com [9.56.224.217]) by d01relay06.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id r5SF9F9D42008646 for ; Fri, 28 Jun 2013 11:09:15 -0400 Received: from d01av03.pok.ibm.com (loopback [127.0.0.1]) by d01av03.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id r5SF9EWF027556 for ; Fri, 28 Jun 2013 12:09:14 -0300 Received: from ibm-tiger.the-meissners.org (dhcp-9-32-77-206.usma.ibm.com [9.32.77.206]) by d01av03.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id r5SF9EpO027524; Fri, 28 Jun 2013 12:09:14 -0300 Received: by ibm-tiger.the-meissners.org (Postfix, from userid 500) id 9FD8B4458D; Fri, 28 Jun 2013 11:09:13 -0400 (EDT) Date: Fri, 28 Jun 2013 11:09:13 -0400 From: Michael Meissner To: gcc-patches@gcc.gnu.org, dje.gcc@gmail.com, pthaugen@us.ibm.com, bergner@vnet.ibm.com Subject: [PATCH, powerpc], PR 57744, fix quad word atomic instructions to use even/odd registers Message-ID: <20130628150913.GA25849@ibm-tiger.the-meissners.org> Mail-Followup-To: Michael Meissner , gcc-patches@gcc.gnu.org, dje.gcc@gmail.com, pthaugen@us.ibm.com, bergner@vnet.ibm.com MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-12-10) X-TM-AS-MML: No X-Content-Scanned: Fidelis XPS MAILER x-cbid: 13062815-0320-0000-0000-0000001A9C7F X-Virus-Found: No This patch fixes PR 57744, where the compiler did not allocate even/odd register combination for the lqarx and stqcx. instructions. I traced the problem down to the fact that PTImode can only go in even GPRs (in part to support the quad word instructions), while TImode can go in even/odd GPRs as well as the VSX regsiters. In the example that showed the problem, the TImode value is passed to the function in an odd/even register combination. By setting MODES_TIEABLE_P, the compiler no longer assumes that TImode and PTImode automatically share registers. While I was modifying MODES_TIEABLE_P, I also made similar changes for TDmode (which needs even FPR registers), and small integers (which can't go in floating point/VSX registers). This patch bootstraps fine, and has no regressions. Is it ok to apply this patch? [gcc] 2013-06-28 Michael Meissner PR target/57744 * config/rs6000/rs6000.h (SMALL_INT_MODE): New macro, to recognize small integer modes. (MODES_TIEABLE_P): Do not allow PTImode or TDmode to tie with any other modes. Don't allow small integer modes to tie with modes that can go in floating point/VSX registers. Eliminate Altivec vector mode tests, since these are a subset of ALTIVEC or VSX vector modes. Simplify code, to return 0 if testing MODE2 for a condition, if we've already tested MODE1 for the same condition. [gcc/testsuite] 2013-06-28 Michael Meissner PR target/57744 * gcc.target/powerpc/pr57744.c: New test to make sure lqarx and stqcx. get even registers. Index: gcc/config/rs6000/rs6000.h =================================================================== --- gcc/config/rs6000/rs6000.h (revision 200470) +++ gcc/config/rs6000/rs6000.h (working copy) @@ -1172,6 +1172,11 @@ enum data_align { align_abi, align_opt, #define PAIRED_VECTOR_MODE(MODE) \ ((MODE) == V2SFmode) +#define SMALL_INT_MODE(MODE) \ + ((MODE) == QImode \ + || (MODE) == HImode \ + || (MODE) == SImode) + /* Value is TRUE if hard register REGNO can hold a value of machine-mode MODE. */ #define HARD_REGNO_MODE_OK(REGNO, MODE) \ @@ -1180,28 +1185,40 @@ enum data_align { align_abi, align_opt, /* Value is 1 if it is a good idea to tie two pseudo registers when one has mode MODE1 and one has mode MODE2. If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, - for any hard reg, then this must be 0 for correct output. */ + for any hard reg, then this must be 0 for correct output. + + PTImode and TDmode cannot tie with other modes because they are restricted + to even registers, and it would create problems if an odd register was tried + to tie with PTI/TDmode. Similarly, restrict small integer modes + (QI/HI/SImode) from being tied with DImode/TImode/etc. since they can't go in + floating point or VSX registers. */ #define MODES_TIEABLE_P(MODE1, MODE2) \ - (SCALAR_FLOAT_MODE_P (MODE1) \ + ((MODE1) == (MODE2) \ + ? 1 \ + : ((MODE1) == PTImode || (MODE2) == PTImode) \ + ? 0 \ + : ((MODE1) == TDmode || (MODE2) == TDmode) \ + ? 0 \ + : SMALL_INT_MODE (MODE1) \ + ? SMALL_INT_MODE (MODE2) \ + : SMALL_INT_MODE (MODE2) \ + ? 0 \ + : SCALAR_FLOAT_MODE_P (MODE1) \ ? SCALAR_FLOAT_MODE_P (MODE2) \ : SCALAR_FLOAT_MODE_P (MODE2) \ - ? SCALAR_FLOAT_MODE_P (MODE1) \ + ? 0 \ : GET_MODE_CLASS (MODE1) == MODE_CC \ ? GET_MODE_CLASS (MODE2) == MODE_CC \ : GET_MODE_CLASS (MODE2) == MODE_CC \ - ? GET_MODE_CLASS (MODE1) == MODE_CC \ + ? 0 \ : SPE_VECTOR_MODE (MODE1) \ ? SPE_VECTOR_MODE (MODE2) \ : SPE_VECTOR_MODE (MODE2) \ - ? SPE_VECTOR_MODE (MODE1) \ + ? 0 \ : ALTIVEC_OR_VSX_VECTOR_MODE (MODE1) \ ? ALTIVEC_OR_VSX_VECTOR_MODE (MODE2) \ : ALTIVEC_OR_VSX_VECTOR_MODE (MODE2) \ - ? ALTIVEC_OR_VSX_VECTOR_MODE (MODE1) \ - : ALTIVEC_VECTOR_MODE (MODE1) \ - ? ALTIVEC_VECTOR_MODE (MODE2) \ - : ALTIVEC_VECTOR_MODE (MODE2) \ - ? ALTIVEC_VECTOR_MODE (MODE1) \ + ? 0 \ : 1) /* Post-reload, we can't use any new AltiVec registers, as we already Index: gcc/testsuite/gcc.target/powerpc/pr57744.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/pr57744.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/pr57744.c (revision 0) @@ -0,0 +1,37 @@ +/* { dg-do run { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_p8vector_ok } */ +/* { dg-options "-mcpu=power8 -O3" } */ + +typedef unsigned U_16 __attribute__((mode(TI))); + +extern int libat_compare_exchange_16 (U_16 *, U_16 *, U_16, int, int) + __attribute__((__noinline__)); + +/* PR 57744: lqarx/stqcx needs even/odd register pairs. The assembler will + complain if the compiler gets an odd/even register pair. Create a function + which has the 16 byte compare and exchange instructions, but don't actually + execute it, so that we can detect these failures on older machines. */ + +int +libat_compare_exchange_16 (U_16 *mptr, U_16 *eptr, U_16 newval, + int smodel, int fmodel __attribute__((unused))) +{ + if (((smodel) == 0)) + return __atomic_compare_exchange_n (mptr, eptr, newval, 0, 0, 0); + else if (((smodel) != 5)) + return __atomic_compare_exchange_n (mptr, eptr, newval, 0, 4, 0); + else + return __atomic_compare_exchange_n (mptr, eptr, newval, 0, 5, 0); +} + +U_16 a = 1, b = 1, c = -2; +volatile int do_test = 0; + +int main (void) +{ + if (do_test && !libat_compare_exchange_16 (&a, &b, c, 0, 0)) + aborrt (); + + return 0; +}