From patchwork Tue Sep 6 09:23:12 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Greenhalgh X-Patchwork-Id: 75482 Delivered-To: patch@linaro.org Received: by 10.140.106.11 with SMTP id d11csp448239qgf; Tue, 6 Sep 2016 02:24:38 -0700 (PDT) X-Received: by 10.98.106.65 with SMTP id f62mr70402461pfc.107.1473153878268; Tue, 06 Sep 2016 02:24:38 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id j127si20213937pfc.62.2016.09.06.02.24.37 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Sep 2016 02:24:38 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-435308-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-435308-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-435308-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:mime-version:content-type; q=dns; s=default; b=hEsHarWXy7KW/mCoD4nbI1Z9TkLxYGoEcMqs/hi8/kMmPMUSrU jHRMW7opntrJ8JJMUFx+pfXAXX/vULzfoNxiREUDyuz0DSpWy13jfgGOsRGzuKFh 9RvNUWeNfY3JODQE8i1f6/9AHEZaMjfcYS3R/e9zDrXkYBo9HIVycFppk= 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:mime-version:content-type; s= default; bh=phjVqxmcWVIqxbckywBaEax91TA=; b=UL56NTJZHqHTtGBqtsxd LpdRAacwqG1eQXY6gWzHIWwQ2lkNV8ytVy/cdijgV0AifQEWNZPKFozUstI8gMri EiPli2IhGzuoDOzrqZbUePPfhFlKRl42TvSjATRGMXhYUQ/n83UyZ9JhwNc0p0ZW DpER42ZuXEoem5JtCLdwwr8= Received: (qmail 73480 invoked by alias); 6 Sep 2016 09:24:04 -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 73246 invoked by uid 89); 6 Sep 2016 09:24:02 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00, SPF_PASS autolearn=ham version=3.3.2 spammy=machine_mode, teaching, TYPE_MODE, type_mode X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (207.82.80.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 06 Sep 2016 09:23:51 +0000 Received: from EUR01-VE1-obe.outbound.protection.outlook.com (mail-ve1eur01lp0239.outbound.protection.outlook.com [213.199.154.239]) (Using TLS) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-8-MjpOXAl7MCGIfTXyp02MZA-1; Tue, 06 Sep 2016 10:23:45 +0100 Received: from VI1PR0801CA0062.eurprd08.prod.outlook.com (10.168.60.158) by DB5PR0801MB1495.eurprd08.prod.outlook.com (10.167.229.141) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.599.9; Tue, 6 Sep 2016 09:23:43 +0000 Received: from AM1FFO11FD018.protection.gbl (2a01:111:f400:7e00::136) by VI1PR0801CA0062.outlook.office365.com (2603:10a6:800:4d::30) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.609.9 via Frontend Transport; Tue, 6 Sep 2016 09:23:43 +0000 Received: from nebula.arm.com (217.140.96.140) by AM1FFO11FD018.mail.protection.outlook.com (10.174.64.207) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.587.6 via Frontend Transport; Tue, 6 Sep 2016 09:23:42 +0000 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; Tue, 6 Sep 2016 10:23:16 +0100 From: James Greenhalgh To: CC: , Subject: [Patch RFC] Modify excess precision logic to permit FLT_EVAL_METHOD=16 Date: Tue, 6 Sep 2016 10:23:12 +0100 Message-ID: <1473153792-30946-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)(199003)(377424004)(189002)(2351001)(512874002)(110136002)(586003)(36756003)(4610100001)(229853001)(2476003)(104016004)(106466001)(356003)(5890100001)(77096005)(33646002)(246002)(8676002)(26826002)(11100500001)(626004)(8936002)(19580395003)(50226002)(84326002)(92566002)(7846002)(19580405001)(189998001)(2906002)(568964002)(7696003)(86362001)(50986999)(4326007)(305945005)(5660300001)(87936001); DIR:OUT; SFP:1101; SCL:1; SRVR:DB5PR0801MB1495; H:nebula.arm.com; FPR:; SPF:Pass; PTR:fw-tnat.cambridge.arm.com; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; AM1FFO11FD018; 1:7Ee9m0jNLzFjd1ZE5R1+z63i8eDVANAykBC+4Ph4RrBaSTwsAnR/W/MSwLNJ9QuAsf1j5QtOzKqs/sUmyzPFdHmBmpPu/LYSEUXldOomjMJHpBRwjU0JlZgBhAtjmsE0HbULXSPEU+Nt2RrS2R4M4dqUtEAIW1VcitR7J5e5MhfLC2v1v70SRPpt5Qe6CdpelgI2cej0QraYmgyeMXoFBRRlm5Gcj6jYi87XW4oQp6otvwVd7k89Ahctm3apCJIkpFco58Kw2b2HbQWZacrHFic6YQkXjL0chyJbhT1V7XB+H9IrToVuQfsenkDw2Us6Xjt3VGZLBD/UXTszR1kZ08GfC1Sri6dBVpfaWuWbEmGzBdunMXREjAbhShbuCWFl6mJWZogn/O2IpRc7cVlCRC7hA8vxdIHeuFVRRHh6z3v9WU3NOD1+9U7aQzXxrIyUS3L1N3t8Dozeygc/+CZGOlR9hjKy0NGm/mZB2lhynj6C3tUTeVble0pI0RgHkuIZBMuBgUpp+b9eHwj1WFNYeE+EMUQCWdR3tq3c82/iIDbm4Cl4cbtqYcUn10xsJzWmc/pjE/6O5l7xAxx7tdIZLOrjqffs0KdEqvL5cYOeSPI= X-MS-Office365-Filtering-Correlation-Id: f9f52dd5-bcba-49c0-a49f-08d3d6377ef7 X-Microsoft-Exchange-Diagnostics: 1; DB5PR0801MB1495; 2:EAhVWhnsk+zb0zF4DTy5gX/J23GHiUzOgZac9PoGxYvcEgIyZwdJk80KLHFEe1Qktx4WPj9SG7IyDXJw7xNTpZkCd9aiWvaracz7lBCxYD2XBtYEuXE4HjlCERH+X7F4m5HE8B+fj4AyKS25EH4gadJDfjmyOKLm30UukQ6V2IkC0leUqezkSmk36VpPwIlx; 3:PeLo4giSqxQzx545gOh/Jxz/jhM8JeuveoLdILwUr61tDO2Pj91NX/hDNGOTvKcIp9oic1mfqsDtgvVaG+WdiEi4/9UQ05qWWZjTWqZbi/TveVEG0efrQ7cpqhFkSmSnyymjbmszsGS+Mjcx5GdkUsfmVWmfCvRhYosueL6ne9mh69t9YQFkIo1VfLHGP0LUoethQO+JMryf9nshY0nC7oT2onUC6hgBcFVumiwmz73KyVT9Ebp28b5pB1cX6wcsqbDQexvXU9aJRWJ1GgZl3g==; 25:ML67Qw89+mjTErsX72MOW84hXPy0eS1TqP9ba5xH+kyr7PWUek1UNaO3JKCVtgJuHiT6xQW3FDHyRJM+jcABBADU39uszB+MPFEPha0ilAkH/YHrtGorqRaBHbMwV8fpygKyqFFG5SgZiIBgKWlr8LfrdBGEQJS0XtFtavZwy/FbnsrpzuxBdZeDoDwN/Lm3dusa8NE7alGW2lNk0nZrl7JBw7XRQ7+88wd09dt9nRsncBr60saMBZAf3+ChFur/1yewuWsqyxfxp7gUAaSYCoKv1VY/GPeX+VGTfhOJZpRn/Moq9+AyYi3o6nF4FH0bU86NqJJrA9/IfC1FqT+KJPmxRePRat6ZGgNOLijXyZiofD53IOVPJ5sC2ktXDBCj9zBjU9Tf16EY7tU+8oTa5lNk0YHw4U70Sp2pz+JESd2E2Br0g6wKVFNWWdGiB3/0TfSkVzboiffqB+sjOZAnDrhcLrSrZ9C3vRrCjbefMPk= X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(8251501002); SRVR:DB5PR0801MB1495; X-Microsoft-Exchange-Diagnostics: 1; DB5PR0801MB1495; 31:hJyupquplkr0iymfy4M8EMDqSsm9AroTtsiGYChcbhEIgrth0DXH7n1G/CpUaNqJ9SNKIQhCRJ2lBlq7+R4TCnUNHmyoWE+fAZ4E8bdfrVE+ekP15HScir1gBiXW3d0spovBHPczqiohK63ZPQgcQQmL9UFnMi0oNI1zjLo8CnxXwtkdTN0jrVem1oJnBey7yob2TFKDEKP0/hU0KZAcwhBjl9MazEuHTRq6c3EBv37wEmtx40FFG9MlnGHy4hRd; 20:35nwANdjoWWAlqdZ7eXAmP0eYhHPux4SFq8VnWXL5k48U6VdERgfCazSqtvcj+AYZNzzw1HnWsbIv9shydZGkP63z6ydAa95weDofB71GLHEgt61Wm6dP4PUuXyZB6QPw7M4OFt7vlcfGvWCyyOmCA4qk4/YgrkoaORMwhwx3Yw+G/fUo7aQyl0cQ5e1bHd54os41T1q0BsxB4ElcRkE5/CZjoPjVMiefBYLIb3g/ecFWwO35zBq9TA682+6I7wZ NoDisclaimer: True X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(180628864354917); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(102415321)(6040176)(601004)(2401047)(13013025)(13023025)(13024025)(13020025)(5005006)(8121501046)(3002001)(10201501046)(6055026); SRVR:DB5PR0801MB1495; BCL:0; PCL:0; RULEID:; SRVR:DB5PR0801MB1495; X-Microsoft-Exchange-Diagnostics: 1; DB5PR0801MB1495; 4:IzZjyy/fe0VxrYKnH5wlDaP6I8RMIzouwW0LvOpVUj3HYhTbA5w7ZnOB6UQqQYGEb5Y+OHUYGDpeBUfyE3+fj46Kcc/KjL069n9rTGWFBJTi4kX6PmGvoMM5laIMJOPEuoe5I/d8gtqgpgLQ9CQo8XQXMSeZxdi47djcNUUN+0TzIwCd2sNT0SAy0trZfZbWYaWjsLoQs+iajAXaVAoFeYYe2rc5YV6Eks0CvZZP2dXd1CkoPYPzAmpCpgQYRwErsb+Tl/dalCF3UN89XzUuM19YTy5xXI9rMpU8Bi7qFHtiDe17A3rgRx3vqX5VldwVG7ZMWYgc3smI1SIGwKxu/C8Na5xPp//LKZaaTd2ic2IKsKiqDSRHzpWwlqajXpsEd00Nfht99IumAbsNytUB1n99Pu3UbyCsCEXyUghwsAq0WDjDgCVXvrU3S+T54OXmVpFrLVjqLzHOz2oJKkqjVvJcc7BR+oqVKaesbgMHFsqGC3K2UDCc183RfyLKAMBIcmC+PJ/AufIUCRuj+ZAp0eSQHkTq27GvA9gzvDlm5Bc= X-Forefront-PRVS: 0057EE387C X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DB5PR0801MB1495; 23:PD/9g2sgWnoXz4Z3TPppLVeJ8oALKuRMIDnBQ5V?= =?us-ascii?Q?7NMiYTpc76zCZO7yOBRcodpmTHt7ap6OF2pBNegYk6mZM9fvtnixM/ynZwEn?= =?us-ascii?Q?r0epLbNrxjuyNkzVZyIly609sCi9MOTqBpXCuo9Fk7SRzQp+vdQ8zux+W09K?= =?us-ascii?Q?TX9pfVmTXJf13jNudE4bBPBorS9wvXUq8+RrUqHx/YIaU+/fIkCen2yR58RE?= =?us-ascii?Q?qQWVAumT6YHYUl1v93ft9jYcOUZNRqamxPPMzx8kun7zJBGeUiXEP1luWbfT?= =?us-ascii?Q?sm8LroBlBRVsc/OgEBsFlkIOrn4Wp1e91crc23PM7T73Me4sJqplEesJ1csD?= =?us-ascii?Q?cacdojeOh53gB6XOOVlaF7xMV2cYnujNDIYPWZyWnA6CK9+JOnU/CAwx+hDM?= =?us-ascii?Q?7qTeggI2zguHqNE6T8SDnP3Jt4PmkKwqfNpMLI/7k7Y21hTKyJ50luTu5dIk?= =?us-ascii?Q?YU324S+ulLtjMzcCTCZaYFahjCv2qZI8JiEYynOAOTns5x4eN1fWwDugRrni?= =?us-ascii?Q?i82PpuFgMSENmIIAScUAC60aLEcnLPjiJ/VvHuWQ2g37O1sMRh1dDD5gU6OU?= =?us-ascii?Q?2TBbKSblBukO4n/XThRWNMh4mWRTpIoosKFWW4sA6g5RImyiIWSj+V7vyFLI?= =?us-ascii?Q?EO6AR2zByWjQTf/2ftgXNFHoOJolm8GGQHuqBIwyuY74YqeQxas8JsAgG68U?= =?us-ascii?Q?0FxRVPmiLtcxffvjfXuV+PDE+hIvYpAX/vePyQlPnN1AG+j/Bb5TD6virp7M?= =?us-ascii?Q?icpK/CqDEuphXpEicCaIjN5LgBAbzOdQvCTwqt5COOnf9iKweCu9XrgUPktQ?= =?us-ascii?Q?OVja43qJWxw3+QpjtL06XSzXjDjLDc+tQCs48uPlwztDIQ/d41sG5wG0mXHi?= =?us-ascii?Q?UoeyHvCv+XHcxt6p+V1f7n95ZDYherASYkHGEAvEWv7fAyEqNV7fYhqhyFVF?= =?us-ascii?Q?lpiBXnW0tqTUpV1EkgQk3LHqnpUdcV4UJLOj9J2QeNCHvwKeQX3OWk2YZHr/?= =?us-ascii?Q?yvodtj9nr3CkLnJ0/EkyFkZ2wIE/WSCeAHwh79v4i0fc6b2ggNO2rrjgukjw?= =?us-ascii?Q?Qsu7bd/C7B0Z6n4jEEUY2J1iEnVPm?= X-Microsoft-Exchange-Diagnostics: 1; DB5PR0801MB1495; 6:LLei70kJO3YZEpGYgRm7NkEPWUuRzluSO3ye7YeyQblNs2dteuUVPMfh7waGP9Qg0cKBLZ3G+SX7ZHRTjekcRlOn1lP4RhWcpJ0qCFAcrusUfSVq+dipmlP3hw48D7BMXtrIUWfakjsfItuDnzGlEBvAnKlI9iWZ7Fz+QXFz/lyJCo03+eXaOurZ7jY+0ZXK9NQg00pzMZsfFv+JVqeVftrSFQiK0Ilop92r8b+EXjW6O+dHrzR4JY8KkJyVlvo2s0zIxegNPgDfeWaglxGNavliEMRv+Pgo7mdTILhHCWIFFxpGYm9GiSJK/u/T7oTAL1TMJIDxoRFm8k2YHcoxdA==; 5:njFwHuy0S+jSwwBmM+YnZPfXpWTDe5sq80ptR2FJNIOjIdRTWhI/fZkyKtntgvcS1QFDrTWakWWCAywGkEhmdS/H6ZLpMNMj7LwVrOe1W46E8nLCTTJZwtnsPQ/J5DwgFz99fkARh3NsapOO7MjfvA==; 24:NIYtmTbl4aZOcrdRgn9Dp0n4HEFHVV5j7kV9vDqJsEdDZgrN4rAIvEL/ttQaY9u63zHtxrj6VKtI1QTE1NNq1GKgp19nkRxo969peT1bc/U=; 7:/25Rq7LMy2VaC7YZi4avnwFkYTPzvhJ7nGp5LzpZ3Nrg5yfcaUIAtHfAH1IEr9ePYwFrXgyhyfSN56wg0ggMB3Vr6heMFIGwRCia7x8EXP1TSsV4GT4q9X+U2tCpP8t0uplWIpYDwPjZVYHl8lMJtcxR7jGXhE/3wJFBUttCOMQGUCZm3TzWzu6v2iB33RMzGuAENNzKz0WKiLij0wOy2CTuU9suVPuDKimK0Kpg5enq7pHV8FTaBTkmvvaWZmhV SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; DB5PR0801MB1495; 20:xxMZ2QxsjvWrspVmQAJNmV4XG3rNLSAH8RrGd1F4Wg1OrwyGqVfO7gaYnw5378O/CzSkisDG8r53/o26QEdIClGqqYDTc9tpqeCwk3etoYvDnh6cNE7fcxRJot7sRQ1kiUOFVo9nAEOyAhlS7o092H50SXAyNjAGaYf2ygso730= X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Sep 2016 09:23:42.8579 (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: DB5PR0801MB1495 X-MC-Unique: MjpOXAl7MCGIfTXyp02MZA-1 X-IsSubscribed: yes Hi, ISO/IEC TS 18661-3 redefines FLT_EVAL_METHOD. In this patch I'm interested in updating the code in GCC to handle two of the changes. The redefinition of the meanings of {0, 1, 2}, and the meaning of "N" for the specific case of N=16. In ISO/IEC TS 18661-3, these are defined as so: 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 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; When we enable support for _Float16 in AArch64 we would like, where we have the ARMv8.2-A 16-bit floating point extensions available, to evaluate operations to the range and precision of that type. Where we do not have the extensions available, we'd like to evaluate operations to the range and precision of float. This will require adding support for FLT_EVAL_METHOD=16. In most cases this is simply duplicating the exceptions that exist for FLT_EVAL_METHOD==0 and teaching some of the excess-precision logic that it may need to handle _Float16 types if FLT_EVAL_METHOD=0. In this patch, I first add a new enum for the 5 float methods, just to save the repeated magic numbers now we are up to 5 of them. I've added this to flag-types.h, but there may be a better home for it. In c-family/c-cppbuiltin.c I've updated cpp_iec_559_value such that also allow setting __GEC_IEC_559 if FLT_EVAL_METHOD=16, and I've updated c_cpp_builtins to handle the new value, and use the new enum names. Then I've updated init_excess_precision in toplev.c with the new enum names, and with logic to understand that for targets that provide _Float16, we can't set flag_excess_precision to "fast" when FLT_EVAL_METHOD=0. This is because FLT_EVAL_METHOD=0 requires predictably using the precision of float for _Float16 types. In tree.c, I've modified excess_precision_type with the logic discussed above, promoting _Float16 to the appropriate type if we are required to. I've also added a special case that allows promoting to "float" from an _Float16 type in the case that -fexcess-precision=fast. If we don't do this, then the "fast" case will spend more time promoting and demoting between HFmode and SFmode and the consequence will be slower code. Bootstrapped on AArch64 and x86_64. OK? Thanks, James --- gcc/ 2016-09-06 James Greenhalgh * flag-types.h (flt_eval_method): New. * toplev.c (init_excess_precision): Handle FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16. * tree.c (excess_precision_type): Likewise. gcc/c-family/ 2016-09-06 James Greenhalgh * c-cppbuiltin.c (cpp_iec_559_value): Support FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16. (c_cpp_builtins): Likewise. diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c index ee4d233..f278aff 100644 --- a/gcc/c-family/c-cppbuiltin.c +++ b/gcc/c-family/c-cppbuiltin.c @@ -735,10 +735,13 @@ cpp_iec_559_value (void) 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. */ + lack of IEEE 754 support. FLT_EVAL_METHOD_PROMOTE_TO_FLOAT and + FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16 both give predictable excess + precision. */ if (flag_iso && !c_dialect_cxx () - && TARGET_FLT_EVAL_METHOD != 0 + && TARGET_FLT_EVAL_METHOD != FLT_EVAL_METHOD_PROMOTE_TO_FLOAT + && TARGET_FLT_EVAL_METHOD != FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16 && flag_excess_precision_cmdline != EXCESS_PRECISION_STANDARD) ret = 0; if (flag_iso @@ -1118,24 +1121,28 @@ c_cpp_builtins (cpp_reader *pfile) } builtin_define_with_value (macro_name, suffix, 0); 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 = (FLOATN_TYPE_NODE (0) + ? TYPE_MODE (FLOATN_TYPE_NODE (0)) + : VOIDmode); + switch (TARGET_FLT_EVAL_METHOD) + { + 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; + default: + gcc_unreachable (); + } macro_name = (char *) alloca (strlen (name) + sizeof ("__LIBGCC__EXCESS_" "PRECISION__")); diff --git a/gcc/flag-types.h b/gcc/flag-types.h index dd57e16..adfe074 100644 --- a/gcc/flag-types.h +++ b/gcc/flag-types.h @@ -158,6 +158,16 @@ enum excess_precision EXCESS_PRECISION_STANDARD }; +/* The possible values for FLT_EVAL_METHOD. */ +enum flt_eval_method +{ + FLT_EVAL_METHOD_UNPREDICTABLE = -1, + FLT_EVAL_METHOD_PROMOTE_TO_FLOAT = 0, + FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE = 1, + FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE = 2, + FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16 = 16 +}; + /* Type of stack check. */ enum stack_check_type { diff --git a/gcc/toplev.c b/gcc/toplev.c index 66099ec..052f414 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1700,15 +1700,23 @@ init_excess_precision (void) 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). */ + case FLT_EVAL_METHOD_UNPREDICTABLE: + case FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16: + /* Either the target acts unpredictably (-1) or has the required + operations for any type we support. */ flag_excess_precision = EXCESS_PRECISION_FAST; break; - case 1: - case 2: - /* In these cases, predictable excess precision makes + case FLT_EVAL_METHOD_PROMOTE_TO_FLOAT: + /* Most targets will be in this case (FLT_EVAL_METHOD = 0). + If the target supports _Float16, we need to predictably + calculate it in the precision of float, otherwise, we can + use EXCESS_PRECISION_FAST. */ + if (targetm.floatn_mode (16, false) == VOIDmode) + flag_excess_precision = EXCESS_PRECISION_FAST; + break; + case FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE: + case FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE: + /* In these cases, predictable excess precision always makes sense. */ break; default: diff --git a/gcc/tree.c b/gcc/tree.c index 33e6f97..cbab851 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -8836,50 +8836,93 @@ build_complex_type (tree component_type) tree excess_precision_type (tree type) { + int flt_eval_method = TARGET_FLT_EVAL_METHOD; + 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 (float_type_node); if (flag_excess_precision != EXCESS_PRECISION_FAST) { - 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; + machine_mode type_mode = TYPE_MODE (type); + switch (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; - 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; + if (TREE_CODE (TREE_TYPE (type)) != REAL_TYPE) + return NULL_TREE; + machine_mode type_mode = TYPE_MODE (TREE_TYPE (type)); + switch (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: - gcc_unreachable (); } - break; default: break; } } + else + { + /* A special case for EXCESS_PRECISION_FAST if we need to calculate in + at-least-float precision. If this is a _Float16 + type, and we would calculate it in float precision + (FLT_EVAL_METHOD == FLT_EVAL_METHOD_AT_LEAST_FLOAT), then the target + probably doesn't have HFmode operations. We are therefore + likely to generate better code by promoting once here. If we + don't, we'll promote before arithmetic operations so we can use + their SFmode counterparts. */ + if (flt_eval_method == FLT_EVAL_METHOD_PROMOTE_TO_FLOAT + && float16_type_node) + { + if (TREE_CODE (type) == REAL_TYPE + && TYPE_MODE (type) == float16_type_mode) + return float_type_node; + if (TREE_CODE (type) == COMPLEX_TYPE + && TYPE_MODE (TREE_TYPE (type)) == float16_type_mode) + return complex_float_type_node; + } + } return NULL_TREE; }