From patchwork Sun May 29 14:37:06 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Edlinger X-Patchwork-Id: 627504 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.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3rHj5N740tz9t67 for ; Mon, 30 May 2016 00:37:28 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=N53Loapk; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:references:in-reply-to :content-type:mime-version; q=dns; s=default; b=pElMD3vNsfUelo7x e87QSzMC5Peokcvk8kDLhWbF2/vtrIjKFuGEcmJBmt23S2inYI2Ao1Bu0BaYZNfL MPRw6ZTnTSH182mGhzUi1feTzUjp5Ui5l76TzHF/Job3LVEDM3OBHnJfUBZmrTID Ra/Lz6QAN5SHwJrLf0cvMzzJBnM= 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:from :to:cc:subject:date:message-id:references:in-reply-to :content-type:mime-version; s=default; bh=5pB21pZDLTxxN0o/+9xbc0 5Szh0=; b=N53LoapkcOasvjm/4bHBtOVCUaxylrOpicSR9/o7DW4TBDcmGGLHSD Xr8dlznuSkdBe4qrmuTHxBhZsvuPg2ShRXfCbQ5Mw6aK8dZUQgJ0ZuLud3smqtKj 30YR/6S61wvDGExH5/PyfgWUerNv6v5m93i9TSbUlALMdQvc76Stw= Received: (qmail 6520 invoked by alias); 29 May 2016 14:37: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 6511 invoked by uid 89); 29 May 2016 14:37:21 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=no version=3.3.2 spammy=holes, H*r:ip*15.1.497.8, borders, H*r:Frontend X-HELO: BAY004-OMC3S22.hotmail.com Received: from bay004-omc3s22.hotmail.com (HELO BAY004-OMC3S22.hotmail.com) (65.54.190.160) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA256 encrypted) ESMTPS; Sun, 29 May 2016 14:37:11 +0000 Received: from EUR01-VE1-obe.outbound.protection.outlook.com ([65.54.190.187]) by BAY004-OMC3S22.hotmail.com over TLS secured channel with Microsoft SMTPSVC(7.5.7601.23008); Sun, 29 May 2016 07:37:09 -0700 Received: from VE1EUR01FT063.eop-EUR01.prod.protection.outlook.com (10.152.2.56) by VE1EUR01HT252.eop-EUR01.prod.protection.outlook.com (10.152.3.135) with Microsoft SMTP Server (TLS) id 15.1.497.8; Sun, 29 May 2016 14:37:07 +0000 Received: from AM4PR07MB1571.eurprd07.prod.outlook.com (10.152.2.60) by VE1EUR01FT063.mail.protection.outlook.com (10.152.2.179) with Microsoft SMTP Server (TLS) id 15.1.497.8 via Frontend Transport; Sun, 29 May 2016 14:37:07 +0000 Received: from AM4PR07MB1571.eurprd07.prod.outlook.com ([10.165.249.15]) by AM4PR07MB1571.eurprd07.prod.outlook.com ([10.165.249.15]) with mapi id 15.01.0501.016; Sun, 29 May 2016 14:37:07 +0000 From: Bernd Edlinger To: Uros Bizjak CC: "gcc-patches@gcc.gnu.org" , Vladimir Makarov , Richard Biener , Jeff Law , Eric Botcazou Subject: [PING] [PATCH] Fix ICE with x87 asm operands (PR inline-asm/68843) Date: Sun, 29 May 2016 14:37:06 +0000 Message-ID: References: In-Reply-To: authentication-results: spf=softfail (sender IP is 25.152.2.60) smtp.mailfrom=hotmail.de; gmail.com; dkim=none (message not signed) header.d=none; gmail.com; dmarc=none action=none header.from=hotmail.de; received-spf: SoftFail (protection.outlook.com: domain of transitioning hotmail.de discourages use of 25.152.2.60 as permitted sender) x-ms-exchange-messagesentrepresentingtype: 1 x-eopattributedmessage: 0 x-forefront-antispam-report: CIP:25.152.2.60; IPV:NLI; CTRY:GB; EFV:NLI; SFV:NSPM; SFS:(10019020)(98900003); DIR:OUT; SFP:1102; SCL:1; SRVR:VE1EUR01HT252; H:AM4PR07MB1571.eurprd07.prod.outlook.com; FPR:; SPF:SoftFail; MLV:ovrnspm; MX:1; A:1; LANG:en; x-ms-office365-filtering-correlation-id: 21a66b58-ae37-4fa5-48a5-08d387ceb4f2 x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(1601124038)(5061506196)(5061507196)(1603103041)(1601125047); SRVR:VE1EUR01HT252; x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(432015012)(102415321)(82015046); SRVR:VE1EUR01HT252; BCL:0; PCL:0; RULEID:; SRVR:VE1EUR01HT252; x-forefront-prvs: 0957AD37A0 MIME-Version: 1.0 X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-originalarrivaltime: 29 May 2016 14:37:06.9568 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Internet X-MS-Exchange-CrossTenant-id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1EUR01HT252 Hi, ping for the RTL optimization stuff. The problem here is that the code in reg-stack.c pretty much everywhere assumes that the stack registers do not have gaps. IMHO it is not worth to fix the register allocation in a way that would be necessary for that configuration to work correctly. So this patch tries just to detect a situation that can't possibly work and exit cleanly without raising any ICEs. In this case we have a regstack of st(1) only. That is temp_stack.top=0 and temp_stack.reg[0]=FIRST_STACK_REG+1. So it is just by luck that the assertion in line 2522 triggers, because immediately before that we already do std::swap (temp_stack[j], temp_stack[k]) with j=-1 and k=0 in line 2118. That is because of: j = (temp_stack.top - (REGNO (recog_data.operand[i]) - FIRST_STACK_REG)) This formula only works, if you can assume that st(1) can only be used in a stack that has at least two elements. Likewise the return statement in get_hard_regnum: return i >= 0 ? (FIRST_STACK_REG + regstack->top - i) : -1; Which is also the same formula, and in this case it returns FIRST_STACK_REG although the stack only has one element FIRST_STACK_REG+1 aka st(1). On 05/22/16 22:02, Uros Bizjak wrote: > On Sun, May 22, 2016 at 9:00 AM, Bernd Edlinger > wrote: >> Hi! >> >> as described in the PR there are several non-intuitive rules that >> one has to follow to avoid ICEs with x87 asm operands. >> >> This patch adds an explicit rule, that avoids ICE in the first test case and >> removes an unnecessary error message in the second test case. >> >> >> Boot-strapped and regression-tested on x86_64-pc-linux-gnu. >> OK for trunk? > > This patch is actually dealing with two separate problems > > This part: > > @@ -607,7 +631,7 @@ check_asm_stack_operands (rtx_insn *insn) > record any earlyclobber. */ > > for (i = n_outputs; i < n_outputs + n_inputs; i++) > - if (op_alt[i].matches == -1) > + if (op_alt[i].matches == -1 && STACK_REG_P (recog_data.operand[i])) > { > int j; > > is OK, although, I'd written it as: > > > + if (STACK_REG_P (recog_data.operand[i]) && op_alt[i].matches == -1) > > with slightly simplified testcase: > > --cut here-- > int > __attribute__((noinline, noclone)) > test (double y) > { > int a, b; > asm ("fistpl (%1)\n\t" > "movl (%1), %0" > : "=r" (a) > : "r" (&b), "t" (y) > : "st"); > return a; > } > > int > main () > { > int t = -10; > > if (test (t) != t) > __builtin_abort (); > return 0; > } > --cut here-- > > BTW: It looks to me you also don't need all-memory clobber here. > right. > This part is OK, with a testcase you provided it borders on obvious. > However, you will need rtl-optimization approval for the other > problem. > > Uros. > I changed the patch according to your comments, thanks. I have the updated patch attached. Thanks Bernd. gcc: 2016-05-22 Bernd Edlinger PR inline-asm/68843 * reg-stack.c (check_asm_stack_operands): Explicit input arguments must be grouped on top of stack. Don't force early clobber on ordinary reg outputs. testsuite: 2016-05-22 Bernd Edlinger PR inline-asm/68843 * gcc.target/i386/pr68843-1.c: New test. * gcc.target/i386/pr68843-2.c: New test. Index: gcc/reg-stack.c =================================================================== --- gcc/reg-stack.c (revision 236597) +++ gcc/reg-stack.c (working copy) @@ -97,6 +97,9 @@ All implicitly popped input regs must be closer to the top of the reg-stack than any input that is not implicitly popped. + All explicitly referenced input operands may not "skip" a reg. + Otherwise we can have holes in the stack. + 3. It is possible that if an input dies in an insn, reload might use the input reg for an output reload. Consider this example: @@ -461,6 +464,7 @@ check_asm_stack_operands (rtx_insn *insn) char reg_used_as_output[FIRST_PSEUDO_REGISTER]; char implicitly_dies[FIRST_PSEUDO_REGISTER]; + char explicitly_used[FIRST_PSEUDO_REGISTER]; rtx *clobber_reg = 0; int n_inputs, n_outputs; @@ -568,6 +572,7 @@ check_asm_stack_operands (rtx_insn *insn) popped. */ memset (implicitly_dies, 0, sizeof (implicitly_dies)); + memset (explicitly_used, 0, sizeof (explicitly_used)); for (i = n_outputs; i < n_outputs + n_inputs; i++) if (STACK_REG_P (recog_data.operand[i])) { @@ -581,6 +586,8 @@ check_asm_stack_operands (rtx_insn *insn) if (j < n_clobbers || op_alt[i].matches >= 0) implicitly_dies[REGNO (recog_data.operand[i])] = 1; + else if (reg_class_size[(int) op_alt[i].cl] == 1) + explicitly_used[REGNO (recog_data.operand[i])] = 1; } /* Search for first non-popped reg. */ @@ -600,6 +607,23 @@ check_asm_stack_operands (rtx_insn *insn) malformed_asm = 1; } + /* Search for first not-explicitly used reg. */ + for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++) + if (! implicitly_dies[i] && ! explicitly_used[i]) + break; + + /* If there are any other explicitly used regs, that's an error. */ + for (; i < LAST_STACK_REG + 1; i++) + if (explicitly_used[i]) + break; + + if (i != LAST_STACK_REG + 1) + { + error_for_asm (insn, + "explicitly used regs must be grouped at top of stack"); + malformed_asm = 1; + } + /* Enforce rule #3: If any input operand uses the "f" constraint, all output constraints must use the "&" earlyclobber. @@ -607,7 +631,7 @@ check_asm_stack_operands (rtx_insn *insn) record any earlyclobber. */ for (i = n_outputs; i < n_outputs + n_inputs; i++) - if (op_alt[i].matches == -1) + if (STACK_REG_P (recog_data.operand[i]) && op_alt[i].matches == -1) { int j; Index: gcc/testsuite/gcc.target/i386/pr68843-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/pr68843-1.c (revision 0) +++ gcc/testsuite/gcc.target/i386/pr68843-1.c (working copy) @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +double +test () +{ + double x = 1.0; + asm ("fld %1" /* { dg-error "explicitly used regs must be grouped at top of stack" } */ + : "=&t" (x) + : "u" (x)); + return x; +} Index: gcc/testsuite/gcc.target/i386/pr68843-2.c =================================================================== --- gcc/testsuite/gcc.target/i386/pr68843-2.c (revision 0) +++ gcc/testsuite/gcc.target/i386/pr68843-2.c (working copy) @@ -0,0 +1,22 @@ +int +__attribute__((noinline, noclone)) +test (double y) +{ + int a, b; + asm ("fistpl (%1)\n\t" + "movl (%1), %0" + : "=r" (a) + : "r" (&b), "t" (y) + : "st"); + return a; +} + +int +main () +{ + int t = -10; + + if (test (t) != t) + __builtin_abort (); + return 0; +}