From patchwork Fri Nov 11 15:37:23 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Greenhalgh X-Patchwork-Id: 81860 Delivered-To: patch@linaro.org Received: by 10.140.97.165 with SMTP id m34csp1329391qge; Fri, 11 Nov 2016 07:40:01 -0800 (PST) X-Received: by 10.98.160.29 with SMTP id r29mr8059827pfe.103.1478878801690; Fri, 11 Nov 2016 07:40:01 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id n6si10749964pga.123.2016.11.11.07.40.01 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 11 Nov 2016 07:40:01 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-441125-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-441125-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-441125-patch=linaro.org@gcc.gnu.org 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=AUNV4A7GXuP6pa0s 4Mo6jcWprEBhoV/DszGqXz3WHultWSsWT3qqSQMnU+1STsomWrG6RZV0JYi/ENAR m4JlUDweKnYxvAEiRYYbp2YdOM8aFUKP5NTE8Yr2KxJtjdaSvkDdZV8itstI2BNf t9nlvm3iEEUKGDsyPaPNCtcrZcM= 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=AtlMPbc8n9zPTZPMh2Uul/ gW1P0=; b=o036o8E8hDbvi81nhY3oFnsaoxqCneyFvGC+Tv5QpWxHhcF9wQJNTH FThrXlRHhffsXZS1Zehyv8bzy17SIbJBig+y0DDzlAHPT4yTFz1D7kIPB+NBBl0I ihoVAn33dIbIeDajcgZkXsHOMcG7JrqWSuETHmIXozUHE2Fb+ZMTU= Received: (qmail 81283 invoked by alias); 11 Nov 2016 15:38:52 -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 81111 invoked by uid 89); 11 Nov 2016 15:38:50 -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, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS, UNSUBSCRIBE_BODY autolearn=no version=3.3.2 spammy=clamps, sk:complex, widest X-HELO: EUR02-VE1-obe.outbound.protection.outlook.com Received: from mail-eopbgr20076.outbound.protection.outlook.com (HELO EUR02-VE1-obe.outbound.protection.outlook.com) (40.107.2.76) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 11 Nov 2016 15:38:39 +0000 Received: from AM2PR08CA0008.eurprd08.prod.outlook.com (10.162.32.18) by HE1PR0801MB1787.eurprd08.prod.outlook.com (10.168.150.18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.721.10; Fri, 11 Nov 2016 15:38:35 +0000 Received: from DB3FFO11FD017.protection.gbl (2a01:111:f400:7e04::144) by AM2PR08CA0008.outlook.office365.com (2a01:111:e400:843e::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.721.10 via Frontend Transport; Fri, 11 Nov 2016 15:38:34 +0000 Authentication-Results: spf=pass (sender IP is 217.140.96.140) smtp.mailfrom=arm.com; codesourcery.com; dkim=none (message not signed) header.d=none; codesourcery.com; dmarc=bestguesspass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 217.140.96.140 as permitted sender) receiver=protection.outlook.com; client-ip=217.140.96.140; helo=nebula.arm.com; Received: from nebula.arm.com (217.140.96.140) by DB3FFO11FD017.mail.protection.outlook.com (10.47.217.48) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.707.3 via Frontend Transport; Fri, 11 Nov 2016 15:38:34 +0000 X-IncomingTopHeaderMarker: OriginalChecksum:; UpperCasedChecksum:; SizeAsReceived:896; Count:13 Received: from e107456-lin.cambridge.arm.com (10.1.2.79) by mail.arm.com (10.1.105.66) with Microsoft SMTP Server id 14.3.294.0; Fri, 11 Nov 2016 15:38:07 +0000 From: James Greenhalgh To: CC: , , Subject: [Patch 6/17] Migrate excess precision logic to use TARGET_EXCESS_PRECISION Date: Fri, 11 Nov 2016 15:37:23 +0000 Message-ID: <1478878647-22547-7-git-send-email-james.greenhalgh@arm.com> In-Reply-To: <1478878647-22547-1-git-send-email-james.greenhalgh@arm.com> References: <1475254617-10825-1-git-send-email-james.greenhalgh@arm.com> <1478878647-22547-1-git-send-email-james.greenhalgh@arm.com> MIME-Version: 1.0 X-IncomingHeaderCount: 13 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)(377424004)(189002)(199003)(7846002)(305945005)(568964002)(76176999)(2906002)(50986999)(8936002)(356003)(50226002)(4326007)(86362001)(6916009)(2950100002)(6666003)(110136003)(586003)(77096005)(8676002)(104016004)(512874002)(33646002)(92566002)(246002)(5890100001)(2351001)(26826002)(106466001)(84326002)(5660300001)(36756003)(87936001)(2476003)(189998001)(4610100001)(626004); DIR:OUT; SFP:1101; SCL:1; SRVR:HE1PR0801MB1787; H:nebula.arm.com; FPR:; SPF:Pass; PTR:fw-tnat.cambridge.arm.com; MX:1; A:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; DB3FFO11FD017; 1:tLkXR4La6fqyj6aDB48YpjMcS0qmhBhDl347snYljypW2rKTBIS64YkCSplCeJlr1h5eSNcCcVjVUjnwYURjjTt2OMRmNeNiQMj+5SvlotTRQYwt6BGIVJYdZ53kxfyYIlXKtZ32X3BVKJU3PcvzB3GvkSDBvaFqcS2C56yxEcAIEbNUnIYTbPHpeuuSy8rrhXD4YT5IfSPqYMvWoFx7WX4tSXCETgyJ87OliSikfLG5atu/ftLT5aKBum9dF0KM70NflUEiU7HirUv2D5c3POw/CZvj4ejLHpSpk5/c78kQU7NhYX4c+2BvPcze8rdMW+XpRjGKqubn1r4em+X5HlGAwmnWbqEiJF4II8LKvSc5i7RtF5YUD/fgysh2VM2fCKxSkFvYSoMaePhabHjyGFLHVHz1N5cb+z8yPTUQqxHPIDrzHyfB1eZVSt5Rh3+o9mnNkeM8MAiNQuIf7xjs6miXtJd6oX+3/WyTyyHsUpj9Mw7UqCA8d3P24cMxYPFFaq7tCNt07JZVBSSHigXIWVBCa7zhAJgrmq7z/4ZfLmac2S8TM2iM2Od8vA2nRsQzmHycUa0iZhjDtzFRQ6MqiflCMTfMbmweuoWArY9J9Go= X-Microsoft-Exchange-Diagnostics: 1; HE1PR0801MB1787; 2:jnfFgcpbBPGwa8hYjEfBY+VlmtR1o37U4Np/uJBhMo2/kxu/KFFMGoetQq+aL/iHRuzySopKJ0eGpX7kJJbrWG0X3BScUeJHgwFs4MRz09Wn5P7JAguV4qOB7ZSPPDw7OpUgtszRNLeJODzxi8c2hQbcdvTWpwWKL/pwJOs5rJs=; 3:WFgbuyrAR5miUnWEMo80bWEC1CLGZZkCn0wQOGdGfWeUwRnco1Vgt1yiO4MLBePqMdUwEF8vmxEH3kCSd1gUQhqlMVmxGbbdXdvp2KWhfUkMzUUOMjXVBtPJeK71TWIT7WJg3rPFH8tzUJU09sdrxRequGJ2/XT/tOllm/mpixVRX1elrOEyDjqOapGlz1AW+6wjLdRILRLgwCeFgxHPYN44e6Xv1BEG+Q2jRSGKGi9OKbO3d5x3mkStN5Hha88RvaMoJnunuG/8qOe5pCZQBZRAb4L0GTQSL19KTM80pGg= X-MS-Office365-Filtering-Correlation-Id: 2382671c-100c-453c-a7c1-08d40a48cc29 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(8251501002); SRVR:HE1PR0801MB1787; X-Microsoft-Exchange-Diagnostics: 1; HE1PR0801MB1787; 25:GgSVZr+SVGnjgUW+eYICx9gw0Ku8Mu4KrsFXpbQUZ6BMT/IQCH7Tu2vM9t3nNHQL03EabvEJDcM9X8mDqCFWY++UARglCFzEb2JYaLaQ5ClhHAZl9ZKV247SDIKn97XB2K34Wdy4dPxIK0H/yuBK4GJjw65WVccUf1fNxJT+o3Jxh205WDXXrSsQucwv1Ms1WHVzIyWW4FTiwKMoGNL7GivLW9TlAb5e5f2wCkF1ufxuIg5bMxEDkFV2CvvCx40FLWnvTakdD6vRBwGeFBEzC8QLSlcHk1h3TXrS0YE8yHLi1KUue4Ukr2SZoagQvEI1HIe9XEJfhsnsJZotmevHPtqXxmkL/gifskRRKjeJzRPFPFCdq0RXYW0bW0LxYt4H86EDiUxy3tCV4MXK2gG6D21B7tRHASJw3rJstLl4VOER/bgYviI6gLhSDFTRJB69U9vOCRkuC1MMMBbBPwzbtAN8HyeX907b0vCrXT7ug+hbpLdzJTtkq3xgrirfgBeH; 31:piAdA3JJJLg2KoON0J9u0TdUXt5H6UW+1cJaQE69pc4860VMOI0+9n63e0UJFs5pmqbvMTgd1CA0Aake8O/B19aHxcO52T89qAaXzpxc6F6WvalfLovwLBZO+KyQwmwO630s+I93W85Pf/EVuk6+TpyMlHIV5ZoBf/HeSBSpzS6JoLz0a0tpD8Zu+zdP8CaIB7+A8X8tkiIeHx+QLygWtr/nJ8elETICWKjhfZDltWHu0QVhDc+BwSiKP17rRU/SH+omwUFS7lr9HWeMbHa7yg== NoDisclaimer: True X-Microsoft-Exchange-Diagnostics: 1; HE1PR0801MB1787; 20:PiTjSH93VELdz/qShycKCVPZdKS2qC+Q3GUysN1PtVWdq15mP5PfEUMJ+74UmYNxFKL/auWCX6vMU5zz/U4c4po69bUd/SZl52y5lRm6EZOXVW80KRS/0C/V5wNvWV3ibVwQZNY9hsOwNsd7WwqihJ14kRvGhen3oNzSiGHaSDdQNlJO7Q8nlUoqrgoxHqjTe41w3qQEvAq4oAZmuil0vvzr1cg5SahwKPKd7yGI7C9VrvqbTBnLrjRoZSnDt8n7; 4:z6S2MTVFjaSWvW+mwIsguFBi/DHZKzoPR5Ig4D/IYGEeORLb1DOdPI///8N3HDK4DTIOUVb0fEwpOTgzhFokQbNEPdAa3J69H59nLR2xkeHbT6aDupS+tI1pIZLwo3DNkNUoJPXjIKAuxMsGvXCA989TOg41aBpVFEO+ipix9GjVmkZJlJWLAmujhOyb6+q/kAUWW845pw+dOuDov3cc9wFDTZ+3/XEBjGhfVzLf58oK9t2a5ZX5fP71Ilwdu+QwH0n0841wOFLJ2XX4uExUGG6VjUzT2zdRC7sJvSMyBxpUEQsPXsYkX46ydGbMCflilKoXdG6HHBh5DYvsHzOKT0eY5p1G31kESxchnNkFm66yyzR+GStiNpgpU9799jjH7OaQIFlkmPL7JLJ8MguHUd1jZziFxxayKbA63GeneBVWHEf2H3ppYCNkKclRTSCxqUrkdF/hz2HVYo7RC4bWW8g4asvLbKyakKSfcYaNNKjnKoM4HliEXjnJHo2MGTG2E42llzkorXYTnznrA9a/rzSVxZffu8trbLeCE/rlSr+vbVtbXxsOnjBfugaaC2keufAATv1XbtHu23zvpJZxXYmrqcUr6rnnaxEre24P7zxA4HSrQoDIe/1PF7yZ4FPO X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(180628864354917)(22074186197030)(183786458502308); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(102415395)(6040176)(601004)(2401047)(13024025)(5005006)(8121501046)(13023025)(13020025)(13013025)(3002001)(10201501046)(6055026); SRVR:HE1PR0801MB1787; BCL:0; PCL:0; RULEID:; SRVR:HE1PR0801MB1787; X-Forefront-PRVS: 012349AD1C X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; HE1PR0801MB1787; 23:Yq4oj1Hvx+mMBm29oMZ0cBrStzFaZcDPJh9rKF3?= =?us-ascii?Q?NOVurvFQg66WKL06zbcNh2O6kJsK19Q2MNRJnzxjtKtIhtUyEZ9TbLZNJt3/?= =?us-ascii?Q?yEH/K5jFBHwxj7SKNueI553b0rVhu1Vpb4EDtkKTonKuLQh34EmUziDxH0di?= =?us-ascii?Q?1CyvvZJ23YEMgyrjYb6rxWq9vD5WV6A0MhjkZraSS9C1sM45NCydpXja/bYz?= =?us-ascii?Q?gkVDu+nTS3r+FzMiE01IRaQEwXPdgZepcIrh6OXTaNVplkEb9enzYreZi9Lz?= =?us-ascii?Q?rvrGGzXj4/Py7cHHZXnPYVcZ7Rwh3Kxw30Yf8s9wgeRo1fpF6EE4nJs6jXxg?= =?us-ascii?Q?Qx6H8nOH6XomdqTMy5vp2aJHf/42+Bd6wowOLiKlE4zhuZGUsRyEYiKZpFYG?= =?us-ascii?Q?CCpjvuds+A0f37ir0hegwHhQlv4KmTKzG4JstnhlKcRwILxeBKZmEirG29tQ?= =?us-ascii?Q?Rx0q2tRmejk9VRpSuk3WzJNOSyiS1ESUt33HX9Rs76r9LTGVb2+7Yg1WHSTr?= =?us-ascii?Q?AzHiaw6R+/6gGDTG5SXM3D9h9QdIEvMvjM2l3ZsXzvIr7i52JEbjcGeNELp1?= =?us-ascii?Q?0j+U6zWSg/jpxFqQjCfCSkgbKRncW5ZrORrsd2/RKBxso27PZwVrrzbipH7u?= =?us-ascii?Q?HLMjwvph+9QEymYL/nHD70xK3pFgCQIvEZoL9Z4sMtrULBzzSDo0vdSgpzm7?= =?us-ascii?Q?xyIyiIdh+p8Of0PaNfMLVULbzlVp/MR4mS7/Yv537PIsKbTMOWpdoUjRWJGS?= =?us-ascii?Q?LIQ9Mg1IfGSfwyUG9EN+IVfnlf1G3VHNprU9gr5WXuSnq4bomZfXs54LPCSD?= =?us-ascii?Q?tydBmES8TKEa+exC8aFnllj4IqdWQMtXCo7FgTdB4FOOPDztiUfwCNmWr88/?= =?us-ascii?Q?c3GDIBHHjPC/lR4FRlN7/eXxYhK1xHaVIXiPuMJ0PzyK5hAoX6Eumcn7fMEW?= =?us-ascii?Q?djEUjAmGnqjachI9D5Xujj9RZdDaOqWwA/CvS61OwfnRBd8nyKco+qIBdpuK?= =?us-ascii?Q?c2mkfP9w6FDiFq85WQvYj9fNtDAMSS/6E5JVzDoWvJvzSHPebjomr+uHrh8o?= =?us-ascii?Q?nQ9oWgms=3D?= X-Microsoft-Exchange-Diagnostics: 1; HE1PR0801MB1787; 6:IwcUidibQ2wpjBu0G4cROC77kXTwoG/D+p4VJDu4BjgD+9bWt5OcG/4RP0rOIvzMS/u+0/+LNQPIqELO8s3vcTUUO3+u0l7TZ19pkJwgS3HkQaT8DKPmPeRAd+cuvT3DYMIfUXiE3tzJbbM60fVnjPr52vM6vpqK4VIug48eeG9YBkG8/4hghbhDF4mmeIN+0dSl5OFAXrCDJx0k7RdnKclXBzoPCimcl/81TuQ528511ddgVBVM6ayQQmcKA/uYYJgwW7HDQgdceziFs15tRFAQDjORSOQ1EmvLjqKt06puYIdfe3oZX8rt+Rl3OvRwY4K+/7mkX1RcAvT6tIFp0CYVSkcYIT3VQwqq/ntXCqc=; 5:LqbKGG7fqSxF2FOQ37DqtiXEu8ZFBZxnBF7EiJSYXC5EO/fm1uZfm9iuAYImuiy8F1qvE5XGVH9ysKse5vP8+5hyWO/diT+K1jITcJN94E88JhhuOIZ6WHrC1E32f9zdb/gWFBE/5B2Fszk5//gcpxu7g8pB6hFo4YBqUg+c4/M=; 24:hysPQNxQIwbm8BLaF6twO6KK+WCDGZXn+oLheNoeVuSRs9CnGRtlfvlwkSKIEMVzR8vlmWAKbb/Yo0QWhEF2b/uHIxKtqTNHkZN9eOhUZd4= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; HE1PR0801MB1787; 7:cOlPgqHapVBwacf3iamLBFewtvz9Kj2fIsq2RucK3ELszu/qeiZohirGFKzfO4hfx8twdvJuOqTEh7Eg3yEdUgdkvy55tv2qAWy+40+Bzm+v5xeGwIw/PK1D7MQjLN8c2+vidlP3g5SS/gUCOl+muJhssa2d8Sq9tkxwOIEuXxJ2pTp/nx5UfvAocbzAVNb1OLe/03tO5+aM1aK3bRzFoas+27FJUYEe5ypfquzGpjJJV4v/EC7oPukR2t6w0qcS+pvLSb4bitwgPk/mdE2550M8sDgAiPEoVN+HZ68TPB3XRbmcBnRi5JKMNc+exQYS7TpU1TgtTkSBCM+2Q3VEVDZ3h+68aUoVuhjMSgUKd7Q= X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Nov 2016 15:38:34.2947 (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: HE1PR0801MB1787 X-IsSubscribed: yes --- This patch has already been approved: https://gcc.gnu.org/ml/gcc-patches/2016-11/msg00784.html --- 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. 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 return TRUE if the excess precision proposed by the front-end is the excess precision that will actually be used. 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. We also set __FLT_EVAL_METHOD_TS_18661_3__. 4) The logic in c-family/c-cppbuiltin.c::c_cpp_builtin for setting __LIBGCC_*_EXCESS_PRECISION__ . 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. Finally we need to update to return the appropriate value for FLT_EVAL_METHOD based on the new macros we add. 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. Thanks, James --- gcc/ 2016-11-09 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. * ginclude/float.h: Wrap definition of FLT_EVAL_METHOD in __STDC_WANT_IEC_60559_TYPES_EXT__. gcc/c-family/ 2016-11-09 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_TS_18661_3__. gcc/testsuite/ 2016-11-09 James Greenhalgh * gcc.dg/fpermitted-flt-eval-methods_3.c: New. * gcc.dg/fpermitted-flt-eval-methods_4.c: Likewise. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 307862b..9f0b4a6 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -7944,4 +7944,86 @@ cb_get_suggestion (cpp_reader *, const char *goal, return bm.get_best_meaningful_candidate (); } +/* 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 relates 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. + MAYBE_C11_ONLY_P is TRUE if we should check + FLAG_PERMITTED_EVAL_METHODS as to whether we should limit the possible + values we can return to those from C99/C11, 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 maybe_c11_only_p) +{ + if (maybe_c11_only_p + && flag_permitted_flt_eval_methods + == PERMITTED_FLT_EVAL_METHODS_C11) + return c_c11_flt_eval_method (); + else + return c_ts18661_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 547bab2..602a07e 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -1539,6 +1539,11 @@ extern int tm_attr_to_mask (tree); extern tree tm_mask_to_attr (int); extern tree find_tm_attribute (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 70eade1..a735ca0 100644 --- a/gcc/c-family/c-cppbuiltin.c +++ b/gcc/c-family/c-cppbuiltin.c @@ -728,6 +728,31 @@ cpp_atomic_builtins (cpp_reader *pfile) (have_swap[psize]? 2 : 1)); } +/* Return TRUE if the implicit excess precision in which the back-end will + compute floating-point calculations is not more than the explicit + excess precision that the front-end will apply under + -fexcess-precision=[standard|fast]. + + More intuitively, return TRUE if the excess precision proposed by the + front-end is the excess precision that will actually be used. */ + +static bool +c_cpp_flt_eval_method_iec_559 (void) +{ + enum excess_precision_type front_end_ept + = (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD + ? EXCESS_PRECISION_TYPE_STANDARD + : EXCESS_PRECISION_TYPE_FAST); + + enum flt_eval_method back_end + = targetm.c.excess_precision (EXCESS_PRECISION_TYPE_IMPLICIT); + + enum flt_eval_method front_end + = targetm.c.excess_precision (front_end_ept); + + return excess_precision_mode_join (front_end, back_end) == front_end; +} + /* Return the value for __GCC_IEC_559. */ static int cpp_iec_559_value (void) @@ -770,16 +795,17 @@ cpp_iec_559_value (void) || !dfmt->has_signed_zero) ret = 0; - /* In strict C standards conformance mode, consider unpredictable - excess precision to mean lack of IEEE 754 support. The same - applies to unpredictable contraction. For C++, and outside - strict conformance mode, do not consider these options to mean - lack of IEEE 754 support. */ + /* In strict C standards conformance mode, consider a back-end providing + more implicit excess precision than the explicit excess precision + the front-end options would require to mean a lack of IEEE 754 + support. For C++, and outside strict conformance mode, do not consider + this to mean a 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) @@ -1044,9 +1070,22 @@ c_cpp_builtins (cpp_reader *pfile) builtin_define_with_int_value ("__GCC_IEC_559_COMPLEX", cpp_iec_559_complex_value ()); - /* float.h needs to know this. */ + /* float.h needs these to correctly set FLT_EVAL_METHOD + + We define two values: + + __FLT_EVAL_METHOD__ + Which, depending on the value given for + -fpermitted-flt-eval-methods, may be limited to only those values + for FLT_EVAL_METHOD defined in C99/C11. + + __FLT_EVAL_METHOD_TS_18661_3__ + Which always permits the values for FLT_EVAL_METHOD defined in + ISO/IEC TS 18661-3. */ 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_TS_18661_3__", + c_flt_eval_method (false)); /* And decfloat.h needs this. */ builtin_define_with_int_value ("__DEC_EVAL_METHOD__", @@ -1187,25 +1226,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 75ff8ec..a1eb168 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -8961,15 +8961,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/ginclude/float.h b/gcc/ginclude/float.h index 421f735..3df2889 100644 --- a/gcc/ginclude/float.h +++ b/gcc/ginclude/float.h @@ -129,21 +129,73 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \ || (defined (__cplusplus) && __cplusplus >= 201103L) -/* The floating-point expression evaluation method. - -1 indeterminate - 0 evaluate all operations and constants just to the range and - precision of the type - 1 evaluate operations and constants of type float and double - to the range and precision of the double type, evaluate - long double operations and constants to the range and - precision of the long double type - 2 evaluate all operations and constants to the range and - precision of the long double type +/* The floating-point expression evaluation method. The precise + definitions of these values are generalised to include support for + the interchange and extended types defined in ISO/IEC TS 18661-3. + Prior to this (for C99/C11) the definitions were: + + -1 indeterminate + 0 evaluate all operations and constants just to the range and + precision of the type + 1 evaluate operations and constants of type float and double + to the range and precision of the double type, evaluate + long double operations and constants to the range and + precision of the long double type + 2 evaluate all operations and constants to the range and + precision of the long double type + + The TS 18661-3 definitions are: + + -1 indeterminate + 0 evaluate all operations and constants, whose semantic type has + at most the range and precision of float, to the range and + precision of float; evaluate all other operations and constants + to the range and precision of the semantic type. + 1 evaluate all operations and constants, whose semantic type has + at most the range and precision of double, to the range and + precision of double; evaluate all other operations and constants + to the range and precision of the semantic type. + 2 evaluate all operations and constants, whose semantic type has + at most the range and precision of long double, to the range and + precision of long double; evaluate all other operations and + constants to the range and precision of the semantic type. + N where _FloatN is a supported interchange floating type + evaluate all operations and constants, whose semantic type has + at most the range and precision of the _FloatN type, to the + range and precision of the _FloatN type; evaluate all other + operations and constants to the range and precision of the + semantic type. + N + 1, where _FloatNx is a supported extended floating type + evaluate operations and constants, whose semantic type has at + most the range and precision of the _FloatNx type, to the range + and precision of the _FloatNx type; evaluate all other + operations and constants to the range and precision of the + semantic type. + + The compiler predefines two macros: + + __FLT_EVAL_METHOD__ + Which, depending on the value given for + -fpermitted-flt-eval-methods, may be limited to only those values + for FLT_EVAL_METHOD defined in C99/C11. + + __FLT_EVAL_METHOD_TS_18661_3__ + Which always permits the values for FLT_EVAL_METHOD defined in + ISO/IEC TS 18661-3. + + Here we want to use __FLT_EVAL_METHOD__, unless + __STDC_WANT_IEC_60559_TYPES_EXT__ is defined, in which case the user + is specifically asking for the ISO/IEC TS 18661-3 types, so we use + __FLT_EVAL_METHOD_TS_18661_3__. ??? This ought to change with the setting of the fp control word; the value provided by the compiler assumes the widest setting. */ #undef FLT_EVAL_METHOD +#ifdef __STDC_WANT_IEC_60559_TYPES_EXT__ +#define FLT_EVAL_METHOD __FLT_EVAL_METHOD_TS_18661_3__ +#else #define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ +#endif /* Number of decimal digits, n, such that any floating-point number in the widest supported floating type with pmax radix b digits can be rounded diff --git a/gcc/testsuite/gcc.dg/fpermitted-flt-eval-methods_3.c b/gcc/testsuite/gcc.dg/fpermitted-flt-eval-methods_3.c new file mode 100644 index 0000000..c7bd756 --- /dev/null +++ b/gcc/testsuite/gcc.dg/fpermitted-flt-eval-methods_3.c @@ -0,0 +1,21 @@ +/* { dg-do run } */ +/* { dg-options "-std=c11" } */ + +/* Test that when compiling with -std=c11, we only see the C99/C11 values + for FLT_EVAL_METHOD. */ + +#include + +int main (int argc, char** argv) +{ + switch (FLT_EVAL_METHOD) + { + case 0: + case 1: + case 2: + case -1: + return 0; + default: + return 1; + } +} diff --git a/gcc/testsuite/gcc.dg/fpermitted-flt-eval-methods_4.c b/gcc/testsuite/gcc.dg/fpermitted-flt-eval-methods_4.c new file mode 100644 index 0000000..a7bbb65 --- /dev/null +++ b/gcc/testsuite/gcc.dg/fpermitted-flt-eval-methods_4.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ +/* { dg-options "-std=c11" } */ + +/* Test that when compiling with -std=c11 and defining + __STDC_WANT_IEC_60559_TYPES_EXT__, we only see the ISO/IEC TS + 18661-3 values for FLT_EVAL_METHOD. */ + +#define __STDC_WANT_IEC_60559_TYPES_EXT__ + +#include + +int main (int argc, char** argv) +{ + switch (__FLT_EVAL_METHOD__) + { + case 0: + case 1: + case 2: + case 16: + case -1: + return 0; + default: + return 1; + } +} diff --git a/gcc/toplev.c b/gcc/toplev.c index 59b84eb..d02ca6c 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1685,41 +1685,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 c155d56..0e497fd 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -8852,50 +8852,99 @@ build_complex_type (tree component_type, bool named) 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; + + /* The target will promote this type in a target-dependent way, so excess + precision ought to leave it alone. */ + if (targetm.promoted_type (type) != NULL_TREE) + 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; }