From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtpout2.vodafonemail.de (smtpout2.vodafonemail.de [145.253.239.133]) by sourceware.org (Postfix) with ESMTPS id DE7B1385C41B for ; Fri, 30 Jul 2021 21:55:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org DE7B1385C41B Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=nexgo.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nexgo.de Received: from smtp.vodafone.de (smtpa05.fra-mediabeam.com [10.2.0.36]) by smtpout2.vodafonemail.de (Postfix) with ESMTP id C06061227A9; Fri, 30 Jul 2021 23:55:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nexgo.de; s=vfde-smtpout-mb-15sep; t=1627682106; bh=PAYuVDtbF/nZz63RYPt3UohGZxjPO/wn7jmKDUE9GD0=; h=From:To:Cc:References:In-Reply-To:Subject:Date; b=NcWh6iim6Kalyvy2DrPaAdEu43ix40mV0NqYk+FzcTPKVsc1MeOfyO6x6U80gM2c/ X2GalfWcDuVEnDCI1lM+1e1w7kDWPuM0hYLMgGKbG9dQOtMTiBxt6zeiNMaW7wCotw zlbxTPGkLlRz9N1RmIxG7asef26Gexbzlq75wB64= Received: from H270 (p5b38f1bc.dip0.t-ipconnect.de [91.56.241.188]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by smtp.vodafone.de (Postfix) with ESMTPSA id 450A314019E; Fri, 30 Jul 2021 21:55:06 +0000 (UTC) Message-ID: From: "Stefan Kanthak" To: "Joseph Myers" Cc: References: <8C3EADB2051345408B320575745C4E56@H270> In-Reply-To: Subject: Re: Are some builtin functions (for example log() vs. sqrt()) more equal than others? Date: Fri, 30 Jul 2021 23:54:07 +0200 Organization: Me, myself & IT MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Windows Mail 6.0.6002.18197 X-MimeOLE: Produced By Microsoft MimeOLE V6.1.7601.24158 X-purgate-type: clean X-purgate-Ad: Categorized by eleven eXpurgate (R) http://www.eleven.de X-purgate: This mail is considered clean (visit http://www.eleven.de for further information) X-purgate: clean X-purgate-size: 4228 X-purgate-ID: 155817::1627682106-00004EF9-B5B45D42/0/0 X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: Fri, 30 Jul 2021 21:55:11 -0000 "Joseph Myers" wrote: > On Fri, 30 Jul 2021, Stefan Kanthak wrote: > >> Joseph Myers wrote: >> >> > None of these are valid constant expressions as defined by the standard >> > (constant expressions cannot involve evaluated function calls). >> >> That's why I ask specifically why GCC bugs on log(log(...)), but not on >> log(sqrt(...) ...)! > > The log(log(1.0)) example you gave would raise divide-by-zero. ARGH, my SILLY fault: I named the first constant "euler" since it should of course be set to 2.71..., i.e. this line should have read const double euler = exp(1.0); Unfortunately I wrote but log(1.0) there and introduced the divide-by-zero. Sorry for the confusion. JFTR; in order to provide a short repro, I stripped down a larger program where the values of a static const double table[] = {log2(0.0), ...}; were to be initialized with several logarithms, which but failed. And while stripping it down, I introduced this bug.-( >> > Some might be accepted as an extension, but I expect that since the >> > optimization for constant arguments is intended for valid calls that >> > would otherwise be executed at runtime, not for static initializers, >> > it's avoiding optimizations that would result in the loss of floating- >> > point exception flag raising. >> >> That's no valid excuse: by the standard, the compiler is free to execute >> static initializers during runtime, before calling the main() routine. > > The point of this extension isn't to accept as much as possible. I expected it the other way 'round. > Rather, it turned out when I implemented standard constant expression rules > for GCC 4.5 that lots of existing code was using just about anything GCC > could fold into a constant in just about any context requiring a constant > expression. So for compatibility with existing, questionable, pre-GCC-4.5 > code, we still allow "expressions that can be folded into a constant" in > various such contexts, with a pedwarn-if-pedantic. But because this > isn't a designed, documented extension or something it's actually considered ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ OK. I searched the docs of course before I wrote in, and only asked because I couldn't find anything about this (non-standard) feature. > good practice to use, the semantics remain "expressions that can be folded > into a constant", with all the dependence that implies on the folding GCC > does for optimization purposes - and that folding is designed for > optimizing code outside of static initializers, not for use in this > extension, with all the corresponding implications for its design. > > So if some expression doesn't get folded to a constant outside of static > initializers (or for that matter, if it does get so folded, but previous > GCC versions didn't accept it in static initializers, since this extension > is about compatibility with existing code), it's not a bug for it not to > be accepted in a static initializer. Thanks for the clarification. > If, outside of static initializers, some of these expressions don't get > folded to a constant *even with -fno-trapping-math*, that's a missed > optimization and it would make sense to improve the compiler to fold them > given -fno-trapping-math. In order to get the larger program compiled, I defined the table inside the function which consumed it: double function(...) { const double table[] = {log2(0.0), ...}; ... } GCC evaluated almost all logarithms during compile time and placed them in the .rodata section. BUT: instead to transfer these precomputed constants in the prolog of this function with a call to memcpy() from .rodata to the stack, GCC created a whole lot of movq .LC1...(%rip), %xmm0 movq %xmm0, offset(%rsp) instruction pairs ... one for each precomputed constant. I expected GCC to be a LITTLE smarter there... > Executing static initializers at runtime seems more like a C++ thing; it's > not within the conventional concept of how C maps to object files. regards Stefan