From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x632.google.com (mail-pl1-x632.google.com [IPv6:2607:f8b0:4864:20::632]) by sourceware.org (Postfix) with ESMTPS id F23D73857812 for ; Mon, 15 Feb 2021 00:40:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org F23D73857812 Received: by mail-pl1-x632.google.com with SMTP id k22so2790982pll.6 for ; Sun, 14 Feb 2021 16:40:49 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=kC2xI/iU83ib60pQUuf23sroOShZt1TPOrYYXZLgK4U=; b=Q1QmsKQUDeDBzvq1zyT2YTxeG3Za3Qm+hCEkgfG4BVtW2QlrC7D9fL1Y7h+cl0eITh 993fD558xyY8Dc5mVpXHFjcN+9iatjuiNLrxzlvCJWveZ1pTH0b2i7O9kRV0l4nfMU1e 6EfjCk2VeZGJbMLR4aSPTjDUQiwtIWL/iBKC5YqKPu1wh/Lih7t+P/hDPcKO19f2Is1p S6fQkYCyBSVzpZ/Z92H3XFRJdAfP9pYI+nscQx77zMDE9CeQ4E0J2RTtszRFOcXGUQ5m iTDDAIvXwegXm7wJXLDMBbFeF18wKdNVZsjZzJbNl7OKe+hHGzeqmnNKpi0bT4f/ILJm Zyfw== X-Gm-Message-State: AOAM5304WitNK0HjFnrfbc3ASBJuKlefaH9WDX8lnhYT8XlKTnRadL84 e7lGlaMbvc3/t4VK1tKUhl8cIKrzcaipGe/feeb4EXUeoO8= X-Google-Smtp-Source: ABdhPJzI3YM5w1CDeJSjfyuzayPzE3IaADNwNG7U1hkxx+3dfRudAAxxeHelyuy1hMIke66FL6hHCxWwR/A50ePPqlY= X-Received: by 2002:a17:902:7b89:b029:e1:1b46:bcec with SMTP id w9-20020a1709027b89b02900e11b46bcecmr12847176pll.5.1613349649018; Sun, 14 Feb 2021 16:40:49 -0800 (PST) MIME-Version: 1.0 From: Neven Sajko Date: Mon, 15 Feb 2021 00:40:38 +0000 Message-ID: Subject: Doc fix request: C/C++ extended asm empty input constraint To: gcc@gcc.gnu.org Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 15 Feb 2021 00:40:53 -0000 Hello all, There is a long-standing, but undocumented GCC inline assembly feature that's part of the extended asm GCC extension to C and C++: extended asm empty input constraints. As far as I understand the semantics, this is a feature that effectively creates a "fake" load and a "fake" ordering dependency. The distinguishing feature of the empty constraint is that it's possible for the compiler to optimize it (and this seems to work fine with gcc -O3) so that no unnecessary additional code generation happens. Thus this feature is something that is useful for testing C/C++ code, or benchmarking it, or fuzzing it, etc. Note that this feature would then almost always be used without actual assembly instructions in the asm declaration/statement. The feature was luckily mentioned on the GCC mailing lists in the past, here's a quote from https://gcc.gnu.org/pipermail/gcc-help/2015-June/124410.html by David Brown. > But the extra "asm volatile" here with a fake input tells the compiler > that "val" is an input to the (empty) assembly, and must therefore be > calculated before the statement is executed. The empty input constraint > (no "r" or "m") gives the compiler complete freedom about where it wants > to put this fake input - all we are saying is that the value "val" must > be calculated before executing > asm volatile("" :: "" (val)) > Generating assembly from this (using gcc-4.5.1, which is the latest > avr-gcc I have installed at the moment) shows the division being done > before the cli() - the code is optimal and correct, with no unnecessary > memory operations (as you would need by making "val" volatile). There is also a Stack Overflow question where somebody is confused with the lack of documentation: https://stackoverflow.com/questions/63305223/gcc-asm-with-empty-input-operand-constraint This is why I am asking for this feature to be documented. It seems like this would be the most appropriate place: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#InputOperands I would have tried to contribute a doc fix myself, but I couldn't find the sources for the online docs in the GCC Git repository. Lastly, in case it's helpful, here's a short C++ program which demonstrates the behavior in more concrete terms: > #include > > int > main() { > // Greater than or equal to zero. > constexpr int asmV = ASM_V; > > std::vector v{7, 6, 9, 3, 2, 0}; > for (int i{0}; i < (1 << 28); i++) { > for (int j{0}; j < 6; j++) { > v[j]++; > > if constexpr (1 <= asmV) { > asm volatile ("" :: ""(v.size())); > for (auto x: v) { > asm volatile ("" :: ""(x)); > } > } > if constexpr (2 <= asmV) { > asm volatile ("" :: ""(v.size())); > for (auto x: v) { > asm volatile ("" :: ""(x)); > } > } > if constexpr (3 <= asmV) { > asm volatile ("" :: ""(v.size())); > for (auto x: v) { > asm volatile ("" :: ""(x)); > } > } > } > } > > return 0; > } So compile it with, e.g. g++ -std=c++20 -O3 -flto -march=native -D ASM_V=XXX -o XXX asm.cc Where XXX will be 0, 1, 2 and 3. For ASM_V=0 the loop gets optimized out, while for greater values the loop stays. For ASM_V=1, ASM_V=2 and ASM_V=3 the generated code is exactly the same. Thanks, Neven Sajko