From patchwork Sun Jun 5 16:02:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Edlinger X-Patchwork-Id: 630445 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 3rN2g80kzwz9t5Y for ; Mon, 6 Jun 2016 02:03:15 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=CKiZC2Z6; 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=KyAFmAsEul7ma1p+ X20J8eMCthsaZ6JLP6V6dv0CHJQO36DEEeQZ8ieB20M+gQKmAfRU9P5J6QCs6vCH 1M6Q7gat/MqaOai9y/R6VwCC95PVJMONwZ4BcLusW28FZVi4LmwPvpjY2dJL0O9O CHd9MAuUCemKsUmTvs8NQ6VUoKM= 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=kYoBxPd86sfAgaZGkfVNir FD1Yo=; b=CKiZC2Z6pFywqUsh3nGlLjwTZ5E+5UJu2xFCu9AZCtCSB3HUXdOTvU Yrvn6Dy88aIOAM/3N1W9v10wI5grStDXX6pulU2f/2676sxSOvK36Om0eIeXFQ44 qlfAvii4Xed4TvPTbuswFQPMC79RKm69CXAIcFR/y90AVy1XjmIkg= Received: (qmail 48789 invoked by alias); 5 Jun 2016 16:03:08 -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 47826 invoked by uid 89); 5 Jun 2016 16:03:07 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.4 required=5.0 tests=AWL, BAYES_50, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=no version=3.3.2 spammy=extract_insn, Hreceived-spf:domain, Hauthentication-results:smtp.mailfrom, Hreceived-spf:permitted X-HELO: BAY004-OMC2S1.hotmail.com Received: from bay004-omc2s1.hotmail.com (HELO BAY004-OMC2S1.hotmail.com) (65.54.190.76) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA256 encrypted) ESMTPS; Sun, 05 Jun 2016 16:02:57 +0000 Received: from EUR01-DB5-obe.outbound.protection.outlook.com ([65.54.190.124]) by BAY004-OMC2S1.hotmail.com over TLS secured channel with Microsoft SMTPSVC(7.5.7601.23008); Sun, 5 Jun 2016 09:02:56 -0700 Received: from DB5EUR01FT054.eop-EUR01.prod.protection.outlook.com (10.152.4.52) by DB5EUR01HT179.eop-EUR01.prod.protection.outlook.com (10.152.4.161) with Microsoft SMTP Server (TLS) id 15.1.497.8; Sun, 5 Jun 2016 16:02:51 +0000 Received: from AM4PR07MB1571.eurprd07.prod.outlook.com (10.152.4.56) by DB5EUR01FT054.mail.protection.outlook.com (10.152.5.133) with Microsoft SMTP Server (TLS) id 15.1.497.8 via Frontend Transport; Sun, 5 Jun 2016 16:02:51 +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.0506.014; Sun, 5 Jun 2016 16:02:50 +0000 From: Bernd Edlinger To: David Wohlferd , Richard Biener , Andrew Haley CC: Jeff Law , "gcc-patches@gcc.gnu.org" , Richard Henderson , Bernd Schmidt , Jakub Jelinek Subject: [PING] [PATCH] Make basic asm implicitly clobber memory Date: Sun, 5 Jun 2016 16:02:50 +0000 Message-ID: References: <572E281A.40900@redhat.com> <1a51f590-fa00-1339-93e5-78ec054f474c@redhat.com> <78478152-3c66-3798-0b4e-f8172e5849d0@LimeGreenSocks.com> <57418AF0.7030202@redhat.com> <3559cea2-fdc0-f787-f41d-d427ae6b350d@LimeGreenSocks.com>, In-Reply-To: authentication-results: spf=softfail (sender IP is 25.152.4.56) smtp.mailfrom=hotmail.de; redhat.com; dkim=none (message not signed) header.d=none; redhat.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.4.56 as permitted sender) x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [0y1W9av2AcVaBzM705eCuCvL6JUYMQJd] x-eopattributedmessage: 0 x-forefront-antispam-report: CIP:25.152.4.56; IPV:NLI; CTRY:GB; EFV:NLI; SFV:NSPM; SFS:(10019020)(98900003); DIR:OUT; SFP:1102; SCL:1; SRVR:DB5EUR01HT179; H:AM4PR07MB1571.eurprd07.prod.outlook.com; FPR:; SPF:SoftFail; MLV:ovrnspm; MX:1; A:1; LANG:en; x-ms-office365-filtering-correlation-id: 02440332-8add-4581-9d06-08d38d5ad87e x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(1601124038)(5061506196)(5061507196)(1603103041)(1601125047); SRVR:DB5EUR01HT179; x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(432015012)(102415321)(82015046); SRVR:DB5EUR01HT179; BCL:0; PCL:0; RULEID:; SRVR:DB5EUR01HT179; x-forefront-prvs: 09645BAC66 MIME-Version: 1.0 X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-originalarrivaltime: 05 Jun 2016 16:02:50.7027 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Internet X-MS-Exchange-CrossTenant-id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB5EUR01HT179 Ping... I think we all agreed on the general direction of this patch. The patch is basically unchanged from previous version, except one line in doc/extend.texi has been updated. So I would like to ask if it is OK for trunk. Thanks Bernd. gcc/ 2016-05-05 Bernd Edlinger PR c/24414 * cfgexpand.c (expand_asm_loc): Remove handling for ADDR_EXPR. Implicitly clobber memory for basic asm with non-empty assembler string. Use targetm.md_asm_adjust also here. * compare-emim.c (arithmetic_flags_clobber_p): Use asm_noperands here. * final.c (final_scan_insn): Handle basic asm in PARALLEL block. * gimple.c (gimple_asm_clobbers_memory_p): Handle basic asm with non-empty assembler string. * ira.c (compute_regs_asm_clobbered): Use asm_noperands here. * recog.c (asm_noperands): Handle basic asm in PARALLEL block. (decode_asm_operands): Handle basic asm in PARALLEL block. (extract_insn): Handle basic asm in PARALLEL block. * doc/extend.texi: Mention new behavior of basic asm. * config/ia64/ia64 (rtx_needs_barrier): Handle ASM_INPUT here. * config/pa/pa.c (branch_to_delay_slot_p, branch_needs_nop_p, branch_needs_nop_p): Use asm_noperands. gcc/testsuite/ 2016-05-05 Bernd Edlinger PR c/24414 * gcc.target/i386/pr24414.c: New test. Index: gcc/cfgexpand.c =================================================================== --- gcc/cfgexpand.c (revision 231412) +++ gcc/cfgexpand.c (working copy) @@ -2655,9 +2655,6 @@ expand_asm_loc (tree string, int vol, location_t l { rtx body; - if (TREE_CODE (string) == ADDR_EXPR) - string = TREE_OPERAND (string, 0); - body = gen_rtx_ASM_INPUT_loc (VOIDmode, ggc_strdup (TREE_STRING_POINTER (string)), locus); @@ -2664,6 +2661,34 @@ expand_asm_loc (tree string, int vol, location_t l MEM_VOLATILE_P (body) = vol; + /* Non-empty basic ASM implicitly clobbers memory. */ + if (TREE_STRING_LENGTH (string) != 0) + { + rtx asm_op, clob; + unsigned i, nclobbers; + auto_vec input_rvec, output_rvec; + auto_vec constraints; + auto_vec clobber_rvec; + HARD_REG_SET clobbered_regs; + CLEAR_HARD_REG_SET (clobbered_regs); + + clob = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)); + clobber_rvec.safe_push (clob); + + if (targetm.md_asm_adjust) + targetm.md_asm_adjust (output_rvec, input_rvec, + constraints, clobber_rvec, + clobbered_regs); + + asm_op = body; + nclobbers = clobber_rvec.length (); + body = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (1 + nclobbers)); + + XVECEXP (body, 0, 0) = asm_op; + for (i = 0; i < nclobbers; i++) + XVECEXP (body, 0, i + 1) = gen_rtx_CLOBBER (VOIDmode, clobber_rvec[i]); + } + emit_insn (body); } Index: gcc/compare-elim.c =================================================================== --- gcc/compare-elim.c (revision 231412) +++ gcc/compare-elim.c (working copy) @@ -162,7 +162,7 @@ arithmetic_flags_clobber_p (rtx_insn *insn) if (!NONJUMP_INSN_P (insn)) return false; pat = PATTERN (insn); - if (extract_asm_operands (pat)) + if (asm_noperands (pat) >= 0) return false; if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) == 2) Index: gcc/doc/extend.texi =================================================================== --- gcc/doc/extend.texi (revision 231412) +++ gcc/doc/extend.texi (working copy) @@ -7508,7 +7508,7 @@ inside them. GCC has no visibility of symbols in the @code{asm} and may discard them as unreferenced. It also does not know about side effects of the assembler code, such as modifications to memory or registers. Unlike -some compilers, GCC assumes that no changes to either memory or registers +some compilers, GCC assumes that no changes to general purpose registers occur. This assumption may change in a future release. To avoid complications from future changes to the semantics and the @@ -7442,6 +7442,10 @@ all basic @code{asm} blocks use the assembler dial Basic @code{asm} provides no mechanism to provide different assembler strings for different dialects. +For basic @code{asm} with non-empty assembler string GCC assumes +the assembler block does not change any general purpose registers, +but it may read or write any globally accessible variable. + Here is an example of basic @code{asm} for i386: @example Index: gcc/final.c =================================================================== --- gcc/final.c (revision 231412) +++ gcc/final.c (working copy) @@ -2565,6 +2565,10 @@ final_scan_insn (rtx_insn *insn, FILE *file, int o (*debug_hooks->source_line) (last_linenum, last_filename, last_discriminator, is_stmt); + if (GET_CODE (body) == PARALLEL + && GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT) + body = XVECEXP (body, 0, 0); + if (GET_CODE (body) == ASM_INPUT) { const char *string = XSTR (body, 0); Index: gcc/gimple.c =================================================================== --- gcc/gimple.c (revision 231412) +++ gcc/gimple.c (working copy) @@ -2567,6 +2567,10 @@ gimple_asm_clobbers_memory_p (const gasm *stmt) return true; } + /* Non-empty basic ASM implicitly clobbers memory. */ + if (gimple_asm_input_p (stmt) && strlen (gimple_asm_string (stmt)) != 0) + return true; + return false; } Index: gcc/ira.c =================================================================== --- gcc/ira.c (revision 231412) +++ gcc/ira.c (working copy) @@ -2229,7 +2229,7 @@ compute_regs_asm_clobbered (void) { df_ref def; - if (NONDEBUG_INSN_P (insn) && extract_asm_operands (PATTERN (insn))) + if (NONDEBUG_INSN_P (insn) && asm_noperands (PATTERN (insn)) >= 0) FOR_EACH_INSN_DEF (def, insn) { unsigned int dregno = DF_REF_REGNO (def); Index: gcc/recog.c =================================================================== --- gcc/recog.c (revision 231412) +++ gcc/recog.c (working copy) @@ -1470,6 +1470,8 @@ extract_asm_operands (rtx body) /* If BODY is an insn body that uses ASM_OPERANDS, return the number of operands (both input and output) in the insn. + If BODY is an insn body that uses ASM_INPUT with CLOBBERS in PARALLEL, + return 0. Otherwise return -1. */ int @@ -1476,16 +1478,26 @@ int asm_noperands (const_rtx body) { rtx asm_op = extract_asm_operands (CONST_CAST_RTX (body)); - int n_sets = 0; + int i, n_sets = 0; if (asm_op == NULL) - return -1; + { + if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) >= 2 + && GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT) + { + /* body is [(asm_input ...) (clobber (reg ...))...]. */ + for (i = XVECLEN (body, 0) - 1; i > 0; i--) + if (GET_CODE (XVECEXP (body, 0, i)) != CLOBBER) + return -1; + return 0; + } + return -1; + } if (GET_CODE (body) == SET) n_sets = 1; else if (GET_CODE (body) == PARALLEL) { - int i; if (GET_CODE (XVECEXP (body, 0, 0)) == SET) { /* Multiple output operands, or 1 output plus some clobbers: @@ -1540,9 +1552,12 @@ asm_noperands (const_rtx body) the locations of the operands within the insn into the vector OPERAND_LOCS, and the constraints for the operands into CONSTRAINTS. Write the modes of the operands into MODES. + Write the location info into LOC. Return the assembler-template. + If BODY is an insn body that uses ASM_INPUT with CLOBBERS in PARALLEL, + return the basic assembly string. - If MODES, OPERAND_LOCS, CONSTRAINTS or OPERANDS is 0, + If LOC, MODES, OPERAND_LOCS, CONSTRAINTS or OPERANDS is 0, we don't store that info. */ const char * @@ -1603,6 +1618,12 @@ decode_asm_operands (rtx body, rtx *operands, rtx } nbase = i; } + else if (GET_CODE (asmop) == ASM_INPUT) + { + if (loc) + *loc = ASM_INPUT_SOURCE_LOCATION (asmop); + return XSTR (asmop, 0); + } break; } @@ -2244,7 +2265,8 @@ extract_insn (rtx_insn *insn) case PARALLEL: if ((GET_CODE (XVECEXP (body, 0, 0)) == SET && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS) - || GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS) + || GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS + || GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT) goto asm_insn; else goto normal_insn; Index: gcc/testsuite/gcc.target/i386/pr24414.c =================================================================== --- gcc/testsuite/gcc.target/i386/pr24414.c (revision 0) +++ gcc/testsuite/gcc.target/i386/pr24414.c (working copy) @@ -0,0 +1,13 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +int test; + +int +main () +{ + int x = test; + asm ("movl $1,test"); + if (x + test != 1) + __builtin_trap (); + return 0; +} Index: gcc/config/ia64/ia64.c =================================================================== --- gcc/config/ia64/ia64.c (revision 231412) +++ gcc/config/ia64/ia64.c (working copy) @@ -6549,6 +6549,7 @@ rtx_needs_barrier (rtx x, struct reg_flags flags, case USE: case CALL: case ASM_OPERANDS: + case ASM_INPUT: need_barrier |= rtx_needs_barrier (pat, flags, pred); break; Index: gcc/config/pa/pa.c =================================================================== --- gcc/config/pa/pa.c (revision 231412) +++ gcc/config/pa/pa.c (working copy) @@ -6399,7 +6399,7 @@ branch_to_delay_slot_p (rtx_insn *insn) the branch is followed by an asm. */ if (!insn || GET_CODE (PATTERN (insn)) == ASM_INPUT - || extract_asm_operands (PATTERN (insn)) != NULL_RTX + || asm_noperands (PATTERN (insn)) >= 0 || get_attr_length (insn) > 0) break; } @@ -6430,7 +6430,7 @@ branch_needs_nop_p (rtx_insn *insn) return TRUE; if (!(GET_CODE (PATTERN (insn)) == ASM_INPUT - || extract_asm_operands (PATTERN (insn)) != NULL_RTX) + || asm_noperands (PATTERN (insn)) >= 0) && get_attr_length (insn) > 0) break; } @@ -6454,7 +6454,7 @@ use_skip_p (rtx_insn *insn) /* We can't rely on the length of asms, so we can't skip asms. */ if (!insn || GET_CODE (PATTERN (insn)) == ASM_INPUT - || extract_asm_operands (PATTERN (insn)) != NULL_RTX) + || asm_noperands (PATTERN (insn)) >= 0) break; if (get_attr_length (insn) == 4 && jump_insn == next_active_insn (insn))