From patchwork Sun Jan 24 22:23:53 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Wohlferd X-Patchwork-Id: 572487 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 13371140557 for ; Mon, 25 Jan 2016 09:24:40 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=jbMHAv8H; 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 :subject:to:cc:message-id:date:mime-version:content-type; q=dns; s=default; b=x6UfByE2BtWUmtDaKLfeiEpfB3rAxJyxRpc4KxJd8jBdBneTsT 7IUU7HbfnxiIKbptNI/cx5qu1M+1Bf6tpZTt2HrFEzcLJ6YfZQRvB3RCoqEY5mNt FrX1BWbEwDavj/8DEJL+GYJ8wFTbb4GKAbIlKL+01K1NdW8YYY1rZF9g8= 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 :subject:to:cc:message-id:date:mime-version:content-type; s= default; bh=Qm1vEp8wUsJIfMf/jd1hkrOY8Co=; b=jbMHAv8HSduQIWOejJWW zvh3qFVkeZCHmwVH6b/mPCbiFJ/isTzRgdoC5ig+8bUKsNOzps5l7MRD0aX9osE9 VOxQfVvdjf6cvoqJ+c4zuRtmJl/sKNPoyZXGuDH5tvUkW8C+yy+VKnj6hKPwT4EL 79QfYsTtAP+hKdaJCZdjqUA= Received: (qmail 17116 invoked by alias); 24 Jan 2016 22:24:32 -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 16970 invoked by uid 89); 24 Jan 2016 22:24:28 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.6 required=5.0 tests=AWL, BAYES_20, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy=clobbered, difficulties, wohlferd, Wohlferd X-HELO: bosmailout10.eigbox.net Received: from bosmailout10.eigbox.net (HELO bosmailout10.eigbox.net) (66.96.185.10) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Sun, 24 Jan 2016 22:24:26 +0000 Received: from bosmailscan14.eigbox.net ([10.20.15.14]) by bosmailout10.eigbox.net with esmtp (Exim) id 1aNT56-0002ui-5j for gcc-patches@gcc.gnu.org; Sun, 24 Jan 2016 17:24:24 -0500 Received: from [10.115.3.32] (helo=bosimpout12) by bosmailscan14.eigbox.net with esmtp (Exim) id 1aNT56-0004Dc-0e for gcc-patches@gcc.gnu.org; Sun, 24 Jan 2016 17:24:24 -0500 Received: from bosauthsmtp13.yourhostingaccount.com ([10.20.18.13]) by bosimpout12 with id 9yQJ1s00B0GvDVm01yQM65; Sun, 24 Jan 2016 17:24:23 -0500 X-Authority-Analysis: v=2.1 cv=BfVW09d2 c=1 sm=1 tr=0 a=UH8/iCWBfdUmbm4Ft4Vi3Q==:117 a=sZx1nW7oDdbgogxTPqu5Xw==:17 a=pq4jwCggAAAA:8 a=QPcu4mC3AAAA:8 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=C8F9KGFtAAAA:8 a=88b2x-oFWvEA:10 a=7aQ_Q-yQQ-AA:10 a=r77TgQKjGQsHNAKrUKIA:9 a=3_ctu_Sv6z0nRu2C2rwA:9 a=QEXdDO2ut3YA:10 a=CPwqXloNXAQA:10 a=mDV3o1hIAAAA:8 a=TGqYPTVfj0zYFGCk8XQA:9 a=JP4sMbzFdKu0QoQo:21 a=1oG_MGTAz1hMTM3j:21 Received: from [207.118.20.56] (port=50530 helo=[192.168.1.159]) by bosauthsmtp13.eigbox.net with esmtpa (Exim) id 1aNT50-0006QU-2a; Sun, 24 Jan 2016 17:24:18 -0500 From: David Wohlferd Subject: Wonly-top-basic-asm To: "gcc-patches@gcc.gnu.org" , Richard Henderson , jason@redhat.com Cc: segher@kernel.crashing.org, sandra@codesourcery.com, Paul_Koning@Dell.com, Jeff Law , bernds_cb1@t-online.de, Bernd Edlinger , Andrew Haley Message-ID: <56A54EF9.8060006@LimeGreenSocks.com> Date: Sun, 24 Jan 2016 14:23:53 -0800 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.5.1 MIME-Version: 1.0 X-EN-UserInfo: 97390230d6758ac7ebdf93f8c6197d31:931c98230c6409dcc37fa7e93b490c27 X-EN-AuthUser: dw@limegreensocks.com X-EN-OrigIP: 207.118.20.56 X-EN-OrigHost: unknown I'm not sure which 'subsystem maintainer' to include on this as it affects parsers for both C and c++. I've also cc'ed people from the discussion thread. While that ~100 message thread on the gcc list about pr24414 didn't come to any final conclusions about clobbering registers for basic asm, there were a few things people agreed we could do to help users right now: - Update the basic asm docs to describe basic asm's current (and historical) semantics (ie clobber nothing). - Emphasize how that might be different from users' expectations or the behavior of other compilers. - Warn that this could change in future versions of gcc. To avoid impacts from this change, use extended asm. - Implement and document -Wonly-top-basic-asm (disabled by default) as a way to locate affected statements. This patch does these things. You can review the new doc text at http://www.LimeGreenSocks.com/gcc/Basic-Asm.html ChangeLog: 2016-01-24 David Wohlferd * doc/extend.texi: Doc basic asm behavior and new -Wonly-top-basic-asm option. * doc/invoke.texi: Doc new -Wonly-top-basic-asm option. * c-family/c.opt: Define -Wonly-top-basic-asm. * c/c-parser.c: Implement -Wonly-top-basic-asm for C. * cp/parser.c: Implement -Wonly-top-basic-asm for c++. * testsuite/c-c++-common/Wonly-top-basic-asm.c: New tests for -Wonly-top-basic-asm. * testsuite/c-c++-common/Wonly-top-basic-asm-2.c: Ditto. Note that while I have a release on file with FSF, I don't have write access to SVN. dw Index: gcc/c-family/c.opt =================================================================== --- gcc/c-family/c.opt (revision 232773) +++ gcc/c-family/c.opt (working copy) @@ -585,6 +585,10 @@ C++ ObjC++ Var(warn_namespaces) Warning Warn on namespace definition. +Wonly-top-basic-asm +C ObjC ObjC++ C++ Var(warn_only_top_basic_asm) Warning +Warn on unsafe uses of basic asm. + Wsized-deallocation C++ ObjC++ Var(warn_sized_deallocation) Warning EnabledBy(Wextra) Warn about missing sized deallocation functions. Index: gcc/c/c-parser.c =================================================================== --- gcc/c/c-parser.c (revision 232773) +++ gcc/c/c-parser.c (working copy) @@ -5973,7 +5973,18 @@ labels = NULL_TREE; if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto) + { + /* Warn on basic asm used inside of functions, + EXCEPT when in naked functions. Also allow asm(""). */ + if (warn_only_top_basic_asm && (TREE_STRING_LENGTH (str) != 1) ) + if (lookup_attribute ("naked", + DECL_ATTRIBUTES (current_function_decl)) + == NULL_TREE) + warning_at(asm_loc, OPT_Wonly_top_basic_asm, + "asm statement in function does not use extended syntax"); + goto done_asm; + } /* Parse each colon-delimited section of operands. */ nsections = 3 + is_goto; Index: gcc/cp/parser.c =================================================================== --- gcc/cp/parser.c (revision 232773) +++ gcc/cp/parser.c (working copy) @@ -18003,6 +18003,8 @@ bool goto_p = false; required_token missing = RT_NONE; + location_t asm_loc = cp_lexer_peek_token (parser->lexer)->location; + /* Look for the `asm' keyword. */ cp_parser_require_keyword (parser, RID_ASM, RT_ASM); @@ -18161,6 +18163,16 @@ /* If the extended syntax was not used, mark the ASM_EXPR. */ if (!extended_p) { + /* Warn on basic asm used inside of functions, + EXCEPT when in naked functions. Also allow asm(""). */ + if (warn_only_top_basic_asm && + (TREE_STRING_LENGTH (string) != 1)) + if (lookup_attribute("naked", + DECL_ATTRIBUTES (current_function_decl)) + == NULL_TREE) + warning_at(asm_loc, OPT_Wonly_top_basic_asm, + "asm statement in function does not use extended syntax"); + tree temp = asm_stmt; if (TREE_CODE (temp) == CLEANUP_POINT_EXPR) temp = TREE_OPERAND (temp, 0); Index: gcc/doc/extend.texi =================================================================== --- gcc/doc/extend.texi (revision 232773) +++ gcc/doc/extend.texi (working copy) @@ -2903,12 +2903,14 @@ although the function call is live. To keep such calls from being optimized away, put @smallexample -asm (""); +asm ("":::); @end smallexample @noindent (@pxref{Extended Asm}) in the called function, to serve as a special side-effect. +Older code used @code{asm("")}, but newer code should use the extended +@code{asm} format. @item nonnull (@var{arg-index}, @dots{}) @cindex @code{nonnull} function attribute @@ -7458,7 +7460,8 @@ @end table @subsubheading Remarks -Using extended @code{asm} typically produces smaller, safer, and more +Using extended @code{asm} (@pxref{Extended Asm}) typically produces smaller, +safer, and more efficient code, and in most cases it is a better solution than basic @code{asm}. However, there are two situations where only basic @code{asm} can be used: @@ -7487,6 +7490,8 @@ consecutive in the output, put them in a single multi-instruction @code{asm} statement. Note that GCC's optimizers can move @code{asm} statements relative to other code, including across jumps. +Using inputs and outputs with extended @code{asm} can help correctly position +your asm. @code{asm} statements may not perform jumps into other @code{asm} statements. GCC does not know about these jumps, and therefore cannot take @@ -7497,6 +7502,7 @@ assembly code when optimizing. This can lead to unexpected duplicate symbol errors during compilation if your assembly code defines symbols or labels. +Extended @code{asm}'s @samp{%=} may help resolve this. Since GCC does not parse the @var{AssemblerInstructions}, it has no visibility of any symbols it references. This may result in GCC discarding @@ -7516,11 +7522,59 @@ Basic @code{asm} provides no mechanism to provide different assembler strings for different dialects. -Here is an example of basic @code{asm} for i386: +Basic @code{asm} statements within functions do not perform an implicit +"memory" clobber (@pxref{Clobbers}). Also, there is no implicit clobbering +of @emph{any} registers, so (other than "naked" functions which follow the +ABI rules) changed registers must be restored to their original value before +exiting the @code{asm}. While this behavior has not always been documented, +GCC has worked this way since at least v2.95.3. Also, lacking inputs and +outputs means that GCC's optimizers may have difficulties consistently +positioning the basic @code{asm} in the generated code. +The concept of ``clobbering'' does not apply to basic @code{asm} statements +outside of functions (aka top-level asm). + +@strong{Warning!} This "clobber nothing" behavior may be different than how +other compilers treat basic @code{asm}, since the C standards for the +@code{asm} statement provide no guidance regarding these semantics. As a +result, @code{asm} statements that work correctly on other compilers may not +work correctly with GCC (and vice versa), even though they both compile +without error. Also, there is discussion underway about changing GCC to +have basic @code{asm} clobber at least memory and perhaps some (or all) +registers. If implemented, this change may fix subtle problems with +existing @code{asm} statements. However it may break or slow down ones that +were working correctly. + +If your existing code needs clobbers that GCC's basic @code{asm} is not +providing, or if you want to 'future-proof' your asm against possible +changes to basic @code{asm}'s semantics, use extended @code{asm}. +Extended @code{asm} allows you to specify what (if anything) needs to be +clobbered for your code to work correctly. You can use @ref{Warning +Options, @option{-Wonly-top-basic-asm}} to locate basic @code{asm} +statements that may need changes, and refer to +@uref{https://gcc.gnu.org/wiki/ConvertBasicAsmToExtended, How to convert +from basic asm to extended asm} for information about how to perform the +conversion. + +Here is an example of top-level basic @code{asm} for i386 that defines an +asm macro. That macro is then invoked from within a function using +extended @code{asm}: + @example -/* Note that this code will not compile with -masm=intel */ -#define DebugBreak() asm("int $3") +/* Define macro at file scope with basic asm. */ +/* Add macro parameter p to eax. */ +asm(".macro test p\n\t" + "addl $\\p, %eax\n\t" + ".endm"); + +/* Use macro in function using extended asm. It needs */ +/* the "cc" clobber since the flags are changed and uses */ +/* the "a" constraint since it modifies eax. */ +int DoAdd(int value) +@{ + asm("test 5" : "+a" (value) : : "cc"); + return value; +@} @end example @node Extended Asm @@ -8047,7 +8101,7 @@ for @code{d} by specifying both constraints. @anchor{FlagOutputOperands} -@subsection Flag Output Operands +@subsubsection Flag Output Operands @cindex @code{asm} flag output operands Some targets have a special register that holds the ``flags'' for the Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 232773) +++ gcc/doc/invoke.texi (working copy) @@ -5693,6 +5693,21 @@ a structure that has been marked with the @code{designated_init} attribute. +@item -Wonly-top-basic-asm @r{(C and C++ only)} +Warn if basic @code{asm} statements are used inside a function (i.e. not at +top-level/file scope). + +When used inside of functions, basic @code{asm} can result in unexpected and +unwanted variations in behavior between compilers due to how registers are +handled when calling the asm (@pxref{Basic Asm}). The lack of input and +output constraints (@pxref{Extended Asm}) can also make it difficult for +optimizers to correctly and consistently position the output relative to +other code. + +Functions that are marked with the @option{naked} attribute (@pxref{Function +Attributes}) and @code{asm} statements with an empty instruction string are +excluded from this check. + @item -Whsa Issue a warning when HSAIL cannot be emitted for the compiled function or OpenMP construct.