From patchwork Fri Sep 30 16:56:55 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Greenhalgh X-Patchwork-Id: 677144 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 3slyMG23BHz9sdg for ; Sat, 1 Oct 2016 02:58:50 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=MTdmDD6P; 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:in-reply-to:references :mime-version:content-type; q=dns; s=default; b=KOmX/7gHxBQuJUY9 ELQ186LV7hSwQnLAwqQx8w0A09U//zs40EYH6Riyx2Ir0/OD4lEJZCHGHVoA44Ls Ez1prd+erUNIJI5B05WqoRvmtcID+YwYlpXNo0f4RhxrVa3H6NHxYyketwD4+Rtd q6F066LJiNo9N1rh2u5d4SAo/bs= 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:in-reply-to:references :mime-version:content-type; s=default; bh=9FN7jOkd2xHqphMn9Uryt/ V1Ezs=; b=MTdmDD6P8ec5eti+jnHfCfMbkN+QEOh2pjpJR24SF/Ba6JW8d7hXEa 9/OxffTmX2QV/L9SZJ5B2ALbxl3IXEx/tBQTz3OEI4FDDBTQISdJzh04tVEeDB31 Xg91q1/h1T9oecfPxzG/OsoEqgLGTshNCTgRKFbsMwYLhYPSOyx1o= Received: (qmail 62264 invoked by alias); 30 Sep 2016 16:57:40 -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 62160 invoked by uid 89); 30 Sep 2016 16:57:39 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.0 required=5.0 tests=AWL, BAYES_00, SPF_PASS, UNSUBSCRIBE_BODY autolearn=no version=3.3.2 spammy=clamps, warned, briefly, pertinent X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (146.101.78.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 30 Sep 2016 16:57:28 +0000 Received: from EUR01-VE1-obe.outbound.protection.outlook.com (mail-ve1eur01lp0247.outbound.protection.outlook.com [213.199.154.247]) (Using TLS) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-59-ejHtzWnZP6GVKsIuvyNsiA-1; Fri, 30 Sep 2016 17:57:25 +0100 Received: from HE1PR0801CA0042.eurprd08.prod.outlook.com (10.167.184.52) by AM4PR0801MB1443.eurprd08.prod.outlook.com (10.168.5.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.639.5; Fri, 30 Sep 2016 16:57:19 +0000 Received: from DB3FFO11FD031.protection.gbl (2a01:111:f400:7e04::127) by HE1PR0801CA0042.outlook.office365.com (2603:10a6:3:6::52) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.639.5 via Frontend Transport; Fri, 30 Sep 2016 16:57:19 +0000 Received: from nebula.arm.com (217.140.96.140) by DB3FFO11FD031.mail.protection.outlook.com (10.47.217.62) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.629.5 via Frontend Transport; Fri, 30 Sep 2016 16:57:18 +0000 Received: from e107456-lin.cambridge.arm.com (10.1.2.79) by mail.arm.com (10.1.106.66) with Microsoft SMTP Server id 14.3.294.0; Fri, 30 Sep 2016 17:57:10 +0100 From: James Greenhalgh To: CC: Subject: [Patch 6/11] Migrate excess precision logic to use TARGET_EXCESS_PRECISION Date: Fri, 30 Sep 2016 17:56:55 +0100 Message-ID: <1475254617-10825-4-git-send-email-james.greenhalgh@arm.com> In-Reply-To: <1475254617-10825-1-git-send-email-james.greenhalgh@arm.com> References: <1475254617-10825-1-git-send-email-james.greenhalgh@arm.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-Forefront-Antispam-Report: CIP:217.140.96.140; IPV:CAL; SCL:-1; CTRY:GB; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(7916002)(2980300002)(438002)(189002)(199003)(377424004)(50986999)(305945005)(5660300001)(4610100001)(626004)(36756003)(4326007)(5890100001)(189998001)(104016004)(77096005)(11100500001)(87936001)(110136003)(6666003)(2906002)(356003)(86362001)(7846002)(6916009)(2950100002)(450100001)(92566002)(15975445007)(84326002)(26826002)(19580395003)(19580405001)(33646002)(76176999)(568964002)(246002)(229853001)(2351001)(8676002)(586003)(2476003)(50226002)(106466001)(512874002)(8936002); DIR:OUT; SFP:1101; SCL:1; SRVR:AM4PR0801MB1443; H:nebula.arm.com; FPR:; SPF:Pass; PTR:fw-tnat.cambridge.arm.com; MX:1; A:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; DB3FFO11FD031; 1:2/3kXEAY6QGciJwwMrdOGIV38mCb813tB3iv9akrlX74qjxf6O1iC0WRzrmZ2gdo+ZsYyjFwD8pLUGe0K5Q3OrLi2044QQPzNr5Uz0RdyKXO7SLs4Qt0xne43PZqyrVWEtpur+6W96H7DYi6WnzzNLhp1kQeGhOeUOoiEigidHTFQ6ZbHoJtT9l1oG1o1/uQPNYFanSB5kpGiPZHC2jY8YcrlEomnHIT6UVseLzk516I2N3hGVa/+bJ3LxCKrgmR7LjOpvI+6Eiir1yXKqF2pz/Q7JEQRWaSUTGdN/sXdbzmUo3VVBaAStowo9jbJyYGKtDKeraCwm+5ob+BK+zPJCsMh4ws50sHjuSo8PzcaX2TwbWAbQpc0yAXGcPoJEQSfUaJ+6n0I1CzWZ2EQwPpIv+nIG67Dx7in5KD6UyMrmqwcGmWnxF2Cd5DiNvIiiNQ8En96VvCtUcq6VvG3/cQuXKwIaMrJ83lxkB3FtaSGYEpqdgcJa2mzio5Vpa9xBTRtnbaYBZtfVxzi0RwpoldpGci1g9FdfnHVFi3790uo+x7Chj/iJ3mSgoQTtvZlCSu X-MS-Office365-Filtering-Correlation-Id: e89c2df8-e8b8-4b5c-990e-08d3e952d6a4 X-Microsoft-Exchange-Diagnostics: 1; AM4PR0801MB1443; 2:NGKeX/Rdmp/5EPoXdddLtYHqkbFJmSWvy0H5LAqeMwROKVWCO9/Vou5XcrNptWOclbmORWobNmXrnleMZ30srBl9Fv+gpBfTSK5sypma2aCXlkllCuy87mGIva/WnwfOth0MhHNpauLdbHakemKDli9bhPpwqwrUSh9QyBSDTy2XmLvUNchv9EWQKiY4tzHn; 3:PW/iVftWVC5CrwxaTz8dgogSBp7s/Qt8S97T6jZF9uB9ezO7Q53dC4REGfpI0umPQuDQhxoCD7r3xOlSd3ukpgwwumzz4qq0iYsEQNwr++ane4zuN22ILoFgQSGMsVi5nKLaMziPTLHMVG7Oyjrfdv1lfHBOeuCLCq+ggeeCu3PNbj4ZCEVYzgInBn+AEJlpzNkECB8PJXc/x77324H7lzQMLXZH3ZbJrjpNTR9L8a9NBeLJEts/jouUiRPh3kszqxf9ntOJjX9BUA+vTMisKg==; 25:Le0RAay+Qq1yA5fGn6IExVz5pmjHIdtRUpN6fn8f9V7rUtUo3k+1txxJgGXPEd4sLAU9BivuTb3H7jNhQ+d1vWKqQvzDWpi6O44+G0syLv1tltLBpqgEgcMna0g9JBBjHgwH/AZw0Ay4wfkSVYvs9I/BbVOQhqb5ydT+FM0YdBt1hl/+n9KvZZyS/Jw9BxyCKIfJF2egB1TNWPBqRIncOQNIFHEGg52Jx5s530zwkVJFhx04BPnLua7w0gDemBvqdB1nlWSzq7+InaCWSzCYK2zERqeUL7OvXC+miMAYii1+GCq9kNLua55P4KNaoZ0TFbyI6gumeqifHHHTEvA5IJafeNOd55g2w10NMyygs0CYxBwBv3oik55z3TsgRzEj3ro0Sj82DmJkemU6/P++l1VIoX6ypWFsWApOfaHiyx+YP8AD7Yq1V0Q49qCwXPjyWjGeOJA/lMIPBKT5Ls5cSQ== X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(8251501002); SRVR:AM4PR0801MB1443; X-Microsoft-Exchange-Diagnostics: 1; AM4PR0801MB1443; 31:VXuoH8DAxTBBWz+gzftEEEtI3uXUnLIQ7AopOoAQBTBoAteOT6O+7lHfwGY1xRsNZxDtPobC/YsIJOFSdPONWI4Hj94uDvpY0fDqjsd5dKjm3AoxB5W5lHG+U8yRrFeDwm5WqMY4QML1DTKVT3tt4Fr6dWIWv1zlR5RdGcLjes8hik4kpMLdIwvfYAImrZuWTqRdCrSU79tt0WZI5CifhmNWro8rk6yI+9Em4qSGSq7NeCi70Tw4n8lDuQZgvjZ3sSq5yeEKWeUcaUA+wNB9hDCYnm2B+cKfTC8RqXnt/Ak=; 20:PfRRGXa8TEMFY61K3RPnuL++laUxnoUjuo0tFRJYp7erSKOJZAaY4DKsyMwrOHvjovBqORMlU+8q0Ul57YEyE9DHcCbfLK2pRPrzX090MfYYhOEMOFY1KyMHAe+IauJgAv5kzC1D2AFUTRHi5x9BKerADb/PLcCzlRqr6VLP3U1YsJn+Q9QIRQPdZcR/tyFDNHJ+d2rejJSdYFEOR5QRdsk0oqlkTi11PezXlAYlIjhLbIjJEsukbRfOBsSupW11 NoDisclaimer: True X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(180628864354917)(20558992708506)(22074186197030)(183786458502308); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(102415321)(6040176)(601004)(2401047)(13023025)(13013025)(13020025)(13024025)(5005006)(8121501046)(10201501046)(3002001)(6055026); SRVR:AM4PR0801MB1443; BCL:0; PCL:0; RULEID:; SRVR:AM4PR0801MB1443; X-Microsoft-Exchange-Diagnostics: 1; AM4PR0801MB1443; 4:FiqwbsSzqyurheHHCmlWJXBSH2iOtoInCfHgxQiJZPGBP3eXwzg6R6MJerNNlXAjFPd5n5ylMTRpaA2DGT85Uw4DXItIiRIebAH7Jid6HjH2XbQOtm0qdHqW6tkywfhIyyA1aRkt8Q6h1rlJQmwolW0wNcll+/UXnxz2o8q6wavVfrSe4+Dfh57h+iZtbnBzq4KWLhBGCeh7pErhQlhX8S8tK1C7rLcmnGm19SpNKrrQq/O3KC9NbQpTNpxJhowwqvEconCIIBuVbUl7yKY2CClB2oTjiAv0O+zSofhSQLtY3OXB7+Rjnzjbgi6y7XS255Ogi+SG6TvJErYQA/9P/mJD0WKnxOPOCEhMoUErIrmxffhghZ+Lzxb+ibvp+8XoTzEegeOKzy0N9Mc6XoQlak8pkF1W1njzI8a3qzJea4V3qkW73GFpLF4sc2DSTg3CmiWldX2HVwFzU10aJ0GBtojOQQKSPzBQewoR1s04A+QPE9amRUL41ISqU2S6Pm1dEGmX+OExdNfYTJwBEwR6GUY8EtN77sgfiPIP8RkSxjoZYP7uxJ3FroSJ7PCwPj+4A73PuaoC9jEU3Oi6aZVtpIcK/6dizDeXNKeG1e8XYtx7DF1gh7taN+doa8KdVI6bzfSd+RmzCHruW9EvQ+ulig== X-Forefront-PRVS: 008184426E X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM4PR0801MB1443; 23:hCk1a/fc4NeTwOzYMAy2BOt6jVprvByuC5bghz2?= =?us-ascii?Q?Li+YHmakmTTJKZWWr17u81jkWGeheRANkhfCrlw5gldxAW6ODKvlFV5Z/Ul8?= =?us-ascii?Q?Lmn62nPS/HV6TLE/4aO/MFeLcP8tNloGh8SRoNY6H8pb4rAiK3Dc8qoytRHI?= =?us-ascii?Q?KmDjkRUfJHRnrJARJ9Ym2HsId/MZXkpW474miWB3AdBOsiDKEgNYTnBXgOdp?= =?us-ascii?Q?mrDDp98ZouCZfCBQEA1t9P8PtdKQA8jFAdrWBZWer0h1Vf7p6zXRWoTXZAFp?= =?us-ascii?Q?3Ute/IIOEZN6tbRUPj/E4Pfp1VJ5lHrnE0EpIPPgmzr4s0ZyDGfHBjWzTbjK?= =?us-ascii?Q?HSf8RfZOtlvOuLTTWfxw+iIZ4aXNgUiEL+Iy9yPfhrBXifdIwAtDNYN2kT5g?= =?us-ascii?Q?EY2i0S1OE2Mwo45dFa8P19gQfq0XDpDe25vM4vz/ihMYAYZBbZmUPR5PfzAF?= =?us-ascii?Q?VGjnjOQbqSX1kyBoMpuxzH1vtaNxOnhmW1j9dA/496SazJITkw0KivQn/aV4?= =?us-ascii?Q?TjL0q7Mk4uEBM+mFuilCxc0cQuf0vTwDiCdgyXtBI5/vUskYKCb5aZbPN7fF?= =?us-ascii?Q?MSTSb+q5l1UhqWBs6EVcBcqTTm+Wwebu4IUnC3GwvvuvzDtEy5/MWNkfeB+h?= =?us-ascii?Q?Eh/fVWtcM50q+iaZDA2Ii4oy0UdCxH5iJ/zpbJU3xfVJrpTsG+DszpC8m2r+?= =?us-ascii?Q?rqjHlc+kYbQQUvK80wuwf7DHwcC9WrHKQXulUa0IjYaeUmpo66N2qUPRfJcb?= =?us-ascii?Q?gaUVnSjJSqBUVOzafikyoag2MmumCGSgfz4N07zxMW1gKKjOP0n1y8iXwKaT?= =?us-ascii?Q?KgayR2UWs4UsVwQkU8ZsFPv5KDfTynozbwGO3tNLj6aM87X0aIX6xdIOuRQj?= =?us-ascii?Q?ngm9cww5VXX1A31eBPLjd6+RQvA4EXTAm9yLsoDeN9kp7NuCGit4em4slyA5?= =?us-ascii?Q?bzZF5cH6wrKxa+GFuvMrAdCTuiW6QActerHltYCqWUNySL4uKhQqDLgzwiIz?= =?us-ascii?Q?IOezw0FqIy66A3TKVs01syrfwDWQ1DCrdbeoILMgR0HHV0iXmnx1KK9D8UWl?= =?us-ascii?Q?qjKvq2he7hVNc4Rq7sf0zesZW05yKYzfjnyNObusc+Ah6PZfM7s0OCDxJcPr?= =?us-ascii?Q?mXM+BH54A5iT5prwda+k1aZ2JG/XLrPwqxzLIRZS/3/PVepsLGcEYGTaYiLj?= =?us-ascii?Q?z0J87ahff+rD04XCxFBgz4wahp0jVH7v8M8Ws?= X-Microsoft-Exchange-Diagnostics: 1; AM4PR0801MB1443; 6:oCd+HftmG8o7/cbT0b0Tf9WqXXtUXHC0Z0b37/5+71hBBnufa2nwaf7zVg9p/uCBsYSe42W7d9uUZlxYp6AT8xoty8mi8AAmK/0DXVPP6GIVNKXIgP7D3U1p80wAZLCqzR9ghifIq69+mc4NFwOGW0qwaL4k3ZutSwdaxMuHNsyi8cENolGKPpCwdALRGH7CFLnGmxlItWiPr0o/BtPnOWIZygz6SvecwZqqQl3oeuToc3mAUvvDhkuNCOUztArNtrGJ0erKhPOzOAthHdLQqm2YDyxgcFKdRFFI4FHs7sRzsVJqvg3KSNla7pKdrxbch3gm6MYNh1PArbk/DDfBzg==; 5:WwWzf1SwD0YnuSRk2eh6FekObSdBd2GYu/BJRTW5IMvJ79Y5JdZWniGCL3o9fAQgPkDxD2xURtZj+G7B8VnoZjUa8TnEu/f95wfdrZCSiczws9+eui210efBNO60sMAV0aHrJlD+ffNMcmd7AnNjRA==; 24:7169CpmZpgCYf3EKnACKmRRZWfyTIDo0mui6NaFgqWhFyt0Qostm9KbyOrZnSkesKbWBeEsWqxqM8Mmk0LqE670QPU4nl6wcaiOGO7i9+mA=; 7:HB6/l23yk9bZm5JQmtxSGUgu9jTL23p3zIIcY1kgWQHuQvGpMbi2oJfp/sPYW0fjPzZB61EKyqLg9qiDpuZ1A9wDVKpGL/yAjhINK8e8c84IeHkbaWTb2EGl7reKhm5SW7VJN0/Pbayu6C5LfzTQlMhB3xrcV5B1jEFOACt4vzeJ1kDTvVexIVg9+Ne+4sbQeisC272qoIBSHeEss5viIidCwN070v1x4SU/18vf/CC5z3gIJIu4zZdVdjkXm8GOY7/o2hs3qrzSkR+B3rC/0/oCiNuKSOQCHRmn3Fi2qWBH2Rcn6eCUf+j6hWXaZMtt SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM4PR0801MB1443; 20:t7EYnsUbB5dyY6ILbeguWqJ8/KgJWGnP4ARjuU2lG4UneGgPC7lVkPCTg5Y98UdJT2cN1iyO+ggn/swF5tCT/hiE8ZrObqbNS6YPGKQNwQd8hoFQh/hySPzQ87FlrJxYkS/TRIJOHa4jH89NG/OmWQ1H9Id/Y95UIDbVi0ol00A= X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Sep 2016 16:57:18.4577 (UTC) X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[217.140.96.140]; Helo=[nebula.arm.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR0801MB1443 X-MC-Unique: ejHtzWnZP6GVKsIuvyNsiA-1 X-IsSubscribed: yes Hi, This patch moves the logic for excess precision from using the TARGET_FLT_EVAL_METHOD macro to the TARGET_EXCESS_PRECISION hook introduced earlier in the patch series. These logic changes follow Joseph's comments at https://gcc.gnu.org/ml/gcc-patches/2016-09/msg00410.html Briefly; we have four things to change. 1) The logic in tree.c::excess_precision_type . Here we want to ask the target which excess preicion it would like for whichever of -fexcess-precision=standard or -fexcess-precision=fast is in use, then apply that. 2) The logic in c-family/c-cppbuiltin.c::c_cpp_flt_eval_method_iec_559 . We want to update this to ensure that the target claims the same excess precision to be implicitly added to operations that it reports in -fexcess-precision=standard mode. We take the join of these two reported values, and only if the join is equal to the excess precision requested for -fexcess-precision=standard can we set the IEC_559 macro. 3) The logic in c-family/c-cppbuiltin.c::c_cpp_builtin for setting __FLT_EVAL_METHOD__ . Which is now little more complicated, and makes use of -fpermitted-flt-eval-methods from patch 5. 4) The logic in c-family/c-cppbuiltin.c::c_cpp_builtin for setting __LIBGCC_*_EXCESS_PRECISION__ . This can just be the implicit precision reported by the target. Having moved the logic in to those areas, we can simplify toplev.c::init_excess_precision , which now only retains the assert that -fexcess-precision=default has been rewritten by the language front-end, and the set from the command-line variable to the internal variable. The documentation in invoke.texi is not quite right for the impact of -fexcess-precision, so I've rewritten the text to read a little more generic. Bootstrapped on x86_64 and aarch64 with no issues. Thanks, James --- gcc/ 2016-09-30 James Greenhalgh * toplev.c (init_excess_precision): Delete most logic. * tree.c (excess_precision_type): Rewrite to use TARGET_EXCESS_PRECISION. * doc/invoke.texi (-fexcess-precision): Document behaviour in a more generic fashion. gcc/c-family/ 2016-09-30 James Greenhalgh * c-common.c (excess_precision_mode_join): New. (c_ts18661_flt_eval_method): New. (c_c11_flt_eval_method): Likewise. (c_flt_eval_method): Likewise. * c-common.h (excess_precision_mode_join): New. (c_flt_eval_method): Likewise. * c-cppbuiltin.c (c_cpp_flt_eval_method_iec_559): New. (cpp_iec_559_value): Call it. (c_cpp_builtins): Modify logic for __LIBGCC_*_EXCESS_PRECISION__, call c_flt_eval_method to set __FLT_EVAL_METHOD__ and __FLT_EVAL_METHOD_C99__. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 2652259..983f71a 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -13145,4 +13145,83 @@ diagnose_mismatched_attributes (tree olddecl, tree newdecl) return warned; } +/* Return the latice point which is the wider of the two FLT_EVAL_METHOD + modes X, Y. This isn't just >, as the FLT_EVAL_METHOD values added + by C TS 18661-3 for interchange types that are computed in their + native precision are larger than the C11 values for evaluating in the + precision of float/double/long double. If either mode is + FLT_EVAL_METHOD_UNPREDICTABLE, return that. */ + +enum flt_eval_method +excess_precision_mode_join (enum flt_eval_method x, + enum flt_eval_method y) +{ + if (x == FLT_EVAL_METHOD_UNPREDICTABLE + || y == FLT_EVAL_METHOD_UNPREDICTABLE) + return FLT_EVAL_METHOD_UNPREDICTABLE; + + /* GCC only supports one interchange type right now, _Float16. If + we're evaluating _Float16 in 16-bit precision, then flt_eval_method + will be FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16. */ + if (x == FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16) + return y; + if (y == FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16) + return x; + + /* Other values for flt_eval_method are directly comparable, and we want + the maximum. */ + return MAX (x, y); +} + +/* Return the value that should be set for FLT_EVAL_METHOD in the + context of ISO/IEC TS 18861-3. + + This should relate to the effective excess precision seen by the user, + which is the join point of the precision the target requests for + -fexcess-precision={standard,fast} and the implicit excess precision + the target uses. */ + +static enum flt_eval_method +c_ts18661_flt_eval_method (void) +{ + enum flt_eval_method implicit + = targetm.c.excess_precision (EXCESS_PRECISION_TYPE_IMPLICIT); + + enum excess_precision_type flag_type + = (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD + ? EXCESS_PRECISION_TYPE_STANDARD + : EXCESS_PRECISION_TYPE_FAST); + + enum flt_eval_method requested + = targetm.c.excess_precision (flag_type); + + return excess_precision_mode_join (implicit, requested); +} + +/* As c_cpp_ts18661_flt_eval_method, but clamps the expected values to + those that were permitted by C11. That is to say, eliminates + FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16. */ + +static enum flt_eval_method +c_c11_flt_eval_method (void) +{ + return excess_precision_mode_join (c_ts18661_flt_eval_method (), + FLT_EVAL_METHOD_PROMOTE_TO_FLOAT); +} + +/* Return the value that should be set for FLT_EVAL_METHOD. TS18661_P + is TRUE if we are in a context where values from ISO/IEEC TS 18861-3 + are permitted, and FALSE otherwise. See the comments on + c_ts18661_flt_eval_method for what value we choose to set here. */ + +int +c_flt_eval_method (bool ts18661_p) +{ + if (ts18661_p && flag_permitted_flt_eval_methods + == PERMITTED_FLT_EVAL_METHODS_TS_18661) + return c_ts18661_flt_eval_method (); + else + return c_c11_flt_eval_method (); +} + #include "gt-c-family-c-common.h" diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index c88619b..0c94207 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -1532,6 +1532,11 @@ extern bool valid_array_size_p (location_t, tree, tree); extern bool cilk_ignorable_spawn_rhs_op (tree); extern bool cilk_recognize_spawn (tree, tree *); +extern enum flt_eval_method +excess_precision_mode_join (enum flt_eval_method, enum flt_eval_method); + +extern int c_flt_eval_method (bool ts18661_p); + #if CHECKING_P namespace selftest { extern void c_format_c_tests (void); diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c index b860c21..c8d5290 100644 --- a/gcc/c-family/c-cppbuiltin.c +++ b/gcc/c-family/c-cppbuiltin.c @@ -727,6 +727,32 @@ cpp_atomic_builtins (cpp_reader *pfile) (have_swap[psize]? 2 : 1)); } +/* If the join of the implicit precision in which the target will compute + floating-point values and the standard precision in which the target will + compute values is not equal to the standard precision, then the target + is either unpredictable, or is a broken configuration in which it claims + standards compliance, but doesn't honor that. + + Effective predictability for __GCC_IEC_559 in flag_iso_mode, means that + the implicit precision is not wider, or less predictable than the + standard precision. + + Return TRUE if we have been asked to compile with + -fexcess-precision=standard, and following the rules above we are able + to guarantee the standards mode. */ + +static bool +c_cpp_flt_eval_method_iec_559 (void) +{ + enum flt_eval_method implicit + = targetm.c.excess_precision (EXCESS_PRECISION_TYPE_IMPLICIT); + enum flt_eval_method standard + = targetm.c.excess_precision (EXCESS_PRECISION_TYPE_STANDARD); + + return (excess_precision_mode_join (implicit, standard) == standard + && flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD); +} + /* Return the value for __GCC_IEC_559. */ static int cpp_iec_559_value (void) @@ -774,11 +800,12 @@ cpp_iec_559_value (void) applies to unpredictable contraction. For C++, and outside strict conformance mode, do not consider these options to mean lack of IEEE 754 support. */ + if (flag_iso && !c_dialect_cxx () - && TARGET_FLT_EVAL_METHOD != 0 - && flag_excess_precision_cmdline != EXCESS_PRECISION_STANDARD) + && !c_cpp_flt_eval_method_iec_559 ()) ret = 0; + if (flag_iso && !c_dialect_cxx () && flag_fp_contract_mode == FP_CONTRACT_FAST) @@ -1038,8 +1065,18 @@ c_cpp_builtins (cpp_reader *pfile) cpp_iec_559_complex_value ()); /* float.h needs to know this. */ + /* We already have the option -fno-fp-int-builtin-inexact to ensure + certain built-in functions follow TS 18661-1 semantics. It might be + reasonable to have a new option to enable FLT_EVAL_METHOD using new + values. However, I'd be inclined to think that such an option should + be on by default for -std=gnu*, only off for strict conformance modes. + (There would be both __FLT_EVAL_METHOD__ and __FLT_EVAL_METHOD_C99__, + say, predefined macros, so that could also always use the + new value if __STDC_WANT_IEC_60559_TYPES_EXT__ is defined.) */ builtin_define_with_int_value ("__FLT_EVAL_METHOD__", - TARGET_FLT_EVAL_METHOD); + c_flt_eval_method (true)); + builtin_define_with_int_value ("__FLT_EVAL_METHOD_C99__", + c_flt_eval_method (false)); /* And decfloat.h needs this. */ builtin_define_with_int_value ("__DEC_EVAL_METHOD__", @@ -1180,25 +1217,38 @@ c_cpp_builtins (cpp_reader *pfile) gcc_assert (found_suffix); } builtin_define_with_value (macro_name, suffix, 0); + + /* The way __LIBGCC_*_EXCESS_PRECISION__ is used is about + eliminating excess precision from results assigned to + variables - meaning it should be about the implicit excess + precision only. */ bool excess_precision = false; - if (TARGET_FLT_EVAL_METHOD != 0 - && mode != TYPE_MODE (long_double_type_node) - && (mode == TYPE_MODE (float_type_node) - || mode == TYPE_MODE (double_type_node))) - switch (TARGET_FLT_EVAL_METHOD) - { - case -1: - case 2: - excess_precision = true; - break; - - case 1: - excess_precision = mode == TYPE_MODE (float_type_node); - break; - - default: - gcc_unreachable (); - } + machine_mode float16_type_mode = (float16_type_node + ? TYPE_MODE (float16_type_node) + : VOIDmode); + switch (targetm.c.excess_precision + (EXCESS_PRECISION_TYPE_IMPLICIT)) + { + case FLT_EVAL_METHOD_UNPREDICTABLE: + case FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE: + excess_precision = (mode == float16_type_mode + || mode == TYPE_MODE (float_type_node) + || mode == TYPE_MODE (double_type_node)); + break; + + case FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE: + excess_precision = (mode == float16_type_mode + || mode == TYPE_MODE (float_type_node)); + break; + case FLT_EVAL_METHOD_PROMOTE_TO_FLOAT: + excess_precision = mode == float16_type_mode; + break; + case FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16: + excess_precision = false; + break; + default: + gcc_unreachable (); + } macro_name = (char *) alloca (strlen (name) + sizeof ("__LIBGCC__EXCESS_" "PRECISION__")); diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 9cb0b54..ba6dc93 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -8723,15 +8723,14 @@ them to store all pertinent intermediate computations into variables. @item -fexcess-precision=@var{style} @opindex fexcess-precision This option allows further control over excess precision on machines -where floating-point registers have more precision than the IEEE -@code{float} and @code{double} types and the processor does not -support operations rounding to those types. By default, -@option{-fexcess-precision=fast} is in effect; this means that -operations are carried out in the precision of the registers and that -it is unpredictable when rounding to the types specified in the source -code takes place. When compiling C, if -@option{-fexcess-precision=standard} is specified then excess -precision follows the rules specified in ISO C99; in particular, +where floating-point operations occur in a format with more precision or +range than the IEEE standard and interchange floating-point types. By +default, @option{-fexcess-precision=fast} is in effect; this means that +operations may be carried out in a wider precision than the types specified +in the source if that would result in faster code, and it is unpredictable +when rounding to the types specified in the source code takes place. +When compiling C, if @option{-fexcess-precision=standard} is specified then +excess precision follows the rules specified in ISO C99; in particular, both casts and assignments cause values to be rounded to their semantic types (whereas @option{-ffloat-store} only affects assignments). This option is enabled by default for C if a strict diff --git a/gcc/toplev.c b/gcc/toplev.c index 5f80763..9b3abab 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1684,41 +1684,17 @@ backend_init (void) init_regs (); } -/* Initialize excess precision settings. */ +/* Initialize excess precision settings. + + We have no need to modify anything here, just keep track of what the + user requested. We'll figure out any appropriate relaxations + later. */ + static void init_excess_precision (void) { - /* Adjust excess precision handling based on the target options. If - the front end cannot handle it, flag_excess_precision_cmdline - will already have been set accordingly in the post_options - hook. */ gcc_assert (flag_excess_precision_cmdline != EXCESS_PRECISION_DEFAULT); flag_excess_precision = flag_excess_precision_cmdline; - if (flag_unsafe_math_optimizations) - flag_excess_precision = EXCESS_PRECISION_FAST; - if (flag_excess_precision == EXCESS_PRECISION_STANDARD) - { - int flt_eval_method = TARGET_FLT_EVAL_METHOD; - switch (flt_eval_method) - { - case -1: - case 0: - /* Either the target acts unpredictably (-1) or has all the - operations required not to have excess precision (0). */ - flag_excess_precision = EXCESS_PRECISION_FAST; - break; - case 1: - case 2: - /* In these cases, predictable excess precision makes - sense. */ - break; - default: - /* Any other implementation-defined FLT_EVAL_METHOD values - require the compiler to handle the associated excess - precision rules in excess_precision_type. */ - gcc_unreachable (); - } - } } /* Initialize things that are both lang-dependent and target-dependent. diff --git a/gcc/tree.c b/gcc/tree.c index 33e6f97..678e244 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -8836,50 +8836,94 @@ build_complex_type (tree component_type) tree excess_precision_type (tree type) { - if (flag_excess_precision != EXCESS_PRECISION_FAST) + /* The target can give two different responses to the question of + which excess precision mode it would like depending on whether we + are in -fexcess-precision=standard or -fexcess-precision=fast. */ + + enum excess_precision_type requested_type + = (flag_excess_precision == EXCESS_PRECISION_FAST + ? EXCESS_PRECISION_TYPE_FAST + : EXCESS_PRECISION_TYPE_STANDARD); + + enum flt_eval_method target_flt_eval_method + = targetm.c.excess_precision (requested_type); + + /* The target should not ask for unpredictable float evaluation (though + it might advertise that implicitly the evaluation is unpredictable, + but we don't care about that here, it will have been reported + elsewhere). If it does ask for unpredictable evaluation, we have + nothing to do here. */ + gcc_assert (target_flt_eval_method != FLT_EVAL_METHOD_UNPREDICTABLE); + + /* Nothing to do. The target has asked for all types we know about + to be computed with their native precision and range. */ + if (target_flt_eval_method == FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16) + return NULL_TREE; + + machine_mode float16_type_mode = (float16_type_node + ? TYPE_MODE (float16_type_node) + : VOIDmode); + machine_mode float_type_mode = TYPE_MODE (float_type_node); + machine_mode double_type_mode = TYPE_MODE (double_type_node); + + switch (TREE_CODE (type)) { - int flt_eval_method = TARGET_FLT_EVAL_METHOD; - switch (TREE_CODE (type)) - { - case REAL_TYPE: - switch (flt_eval_method) - { - case 1: - if (TYPE_MODE (type) == TYPE_MODE (float_type_node)) - return double_type_node; - break; - case 2: - if (TYPE_MODE (type) == TYPE_MODE (float_type_node) - || TYPE_MODE (type) == TYPE_MODE (double_type_node)) - return long_double_type_node; - break; - default: - gcc_unreachable (); - } - break; - case COMPLEX_TYPE: - if (TREE_CODE (TREE_TYPE (type)) != REAL_TYPE) - return NULL_TREE; - switch (flt_eval_method) - { - case 1: - if (TYPE_MODE (TREE_TYPE (type)) == TYPE_MODE (float_type_node)) - return complex_double_type_node; - break; - case 2: - if (TYPE_MODE (TREE_TYPE (type)) == TYPE_MODE (float_type_node) - || (TYPE_MODE (TREE_TYPE (type)) - == TYPE_MODE (double_type_node))) - return complex_long_double_type_node; - break; - default: - gcc_unreachable (); - } - break; - default: - break; - } + case REAL_TYPE: + { + machine_mode type_mode = TYPE_MODE (type); + switch (target_flt_eval_method) + { + case FLT_EVAL_METHOD_PROMOTE_TO_FLOAT: + if (type_mode == float16_type_mode) + return float_type_node; + break; + case FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE: + if (type_mode == float16_type_mode + || type_mode == float_type_mode) + return double_type_node; + break; + case FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE: + if (type_mode == float16_type_mode + || type_mode == float_type_mode + || type_mode == double_type_mode) + return long_double_type_node; + break; + default: + gcc_unreachable (); + } + break; + } + case COMPLEX_TYPE: + { + if (TREE_CODE (TREE_TYPE (type)) != REAL_TYPE) + return NULL_TREE; + machine_mode type_mode = TYPE_MODE (TREE_TYPE (type)); + switch (target_flt_eval_method) + { + case FLT_EVAL_METHOD_PROMOTE_TO_FLOAT: + if (type_mode == float16_type_mode) + return complex_float_type_node; + break; + case FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE: + if (type_mode == float16_type_mode + || type_mode == float_type_mode) + return complex_double_type_node; + break; + case FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE: + if (type_mode == float16_type_mode + || type_mode == float_type_mode + || type_mode == double_type_mode) + return complex_long_double_type_node; + break; + default: + gcc_unreachable (); + } + break; + } + default: + break; } + return NULL_TREE; }