From patchwork Wed Sep 17 12:44:53 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alfie Richards X-Patchwork-Id: 120424 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E6E3D3858427 for ; Wed, 17 Sep 2025 12:48:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E6E3D3858427 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=selector1 header.b=sGwT4SNk; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=selector1 header.b=sGwT4SNk X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from DUZPR83CU001.outbound.protection.outlook.com (mail-northeuropeazon11012019.outbound.protection.outlook.com [52.101.66.19]) by sourceware.org (Postfix) with ESMTPS id C8C143858427 for ; Wed, 17 Sep 2025 12:46:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C8C143858427 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org C8C143858427 Authentication-Results: server2.sourceware.org; arc=pass smtp.remote-ip=52.101.66.19 ARC-Seal: i=3; a=rsa-sha256; d=sourceware.org; s=key; t=1758113184; cv=pass; b=LgBTrKwO/wdRYM2SCE7Gp3QDfdFb7M0evpQDCqbdsKgnMk1wUpWZi0BhjZl+wFE2zY+HU/SV64uiK7AbAS/0SX5+MoFn8+nQB59IsdFXD1vdE70vHmUKv49cY8/WcoA0zk9PkBp5Vy8JgMwCAiOBR04K/9QsubPdfKO5gxmZB8c= ARC-Message-Signature: i=3; a=rsa-sha256; d=sourceware.org; s=key; t=1758113184; c=relaxed/simple; bh=4wRTWnckeIcQDR0u5toC5tba5GblSASMfm2ar+YoU9E=; h=DKIM-Signature:DKIM-Signature:From:To:Subject:Date:Message-ID: MIME-Version; b=NNXe3x6AYbwfI9aAfKjTblqD3fRNSvrgvFyTTlkqmV9WlYdwoKTZ5UF53F4fh6/ojU8u0+QOPba1bMHzzY8SFYYtL1UgLO5fP5YYokN+qXuRNOuQlyEOmKEk9G6da7Jktt8XnyclrRx50yLaqR3PQWBKn5nEsMr4QPaCyZE46Jc= ARC-Authentication-Results: i=3; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C8C143858427 ARC-Seal: i=2; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=pass; b=fFMRuEER/2xbTqLjjBuhfRm0lMfi7+fNlE/wjLvTThZ/lD3p62InGUo9mBKURdSS5UvbrtN9jdO1AkG1WxJ49Ztv+0HOMvZZG10uCOF+RlHnmyymDbIWz/IlZ+dih4/h9sCL7//FOMiTpVej0VZZpE7Pf4xP4S5YNDuCwfW5zLcSwkN0ULbTStouqWS8MozzMyqzJmaaB/kO/JGOWIhGD8tkeltDjzA8OCP/70cxc2L+Bqf9/P7JHUpV4SqE4RntLJlFx08T9Q7b5cuhs+VhPXvigud3j8H3n1bObJHTMbyJGKcgSc6KneQKC7twmB7ncA+iJQ71lw/KHzFCR3oH4g== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=hA5qmvYL3p1q4e3g3ow+pZKiWpUAb6Bo4DPYbGBLqQk=; b=TP3V5chPasFq+YLNdd3+hG6bk5iKVBojlQN3Fo3qj3uouGNf+2h0m1JMgLgFutfQm9MRSYB5kjq1Ue3r0akP6VlYMgn5cu651kzeDN81YfiJqzjKHMdxgzQXRWDefKkc0ov343Pd6NaES0kZp76t++4vIt/mvyUYs3Y4wJGGx/zwty5BqxL5NqFYbVedNWpvanzNZPoEqwCKYK6H6ip0E+lyp8SJnfukuHQ9RIoJc3Ba/UZvp3HFYjbt5Uh0+3h/UuW0E93p0uuSFfmqFwak0ac+ns8+cCb49kQJRIhc2SH8It5ykRBhRe9+7DrFhqvWmrNaYLI/wmK2qDgJaqgTtA== ARC-Authentication-Results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 4.158.2.129) smtp.rcpttodomain=gcc.gnu.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=pass (signature was verified) header.d=arm.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dmarc=[1,1,header.from=arm.com]) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=arm.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=hA5qmvYL3p1q4e3g3ow+pZKiWpUAb6Bo4DPYbGBLqQk=; b=sGwT4SNkgjcxcCpccUWbH0l+J4M6Pwa21EMFr8M6P+xvMqaIVc9Xlq6LxFdhexVYheRvsBwSU9rrADs+3v72DIwZKXkCGLMOhalkdAc1Sr8LgPHXeEV3pt+C78lxuEb6Kag3fijPDeXbocCFAkiZE9hU3R3MC7HdjmrRd/JW898= Received: from AM0PR02CA0075.eurprd02.prod.outlook.com (2603:10a6:208:154::16) by DB9PR08MB6443.eurprd08.prod.outlook.com (2603:10a6:10:261::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9115.22; Wed, 17 Sep 2025 12:46:17 +0000 Received: from AMS0EPF00000191.eurprd05.prod.outlook.com (2603:10a6:208:154:cafe::6c) by AM0PR02CA0075.outlook.office365.com (2603:10a6:208:154::16) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.13 via Frontend Transport; Wed, 17 Sep 2025 12:46:17 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 4.158.2.129) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=arm.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 4.158.2.129 as permitted sender) receiver=protection.outlook.com; client-ip=4.158.2.129; helo=outbound-uk1.az.dlp.m.darktrace.com; pr=C Received: from outbound-uk1.az.dlp.m.darktrace.com (4.158.2.129) by AMS0EPF00000191.mail.protection.outlook.com (10.167.16.216) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Wed, 17 Sep 2025 12:46:15 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=zMqNEwUkj/lNpXCkewKAgdXGu1dB/lu6F4ldITpQ2D2qfmwE610PBVDYFo9nx4Tb6ascVgfm8ns3MdMRKT62rl23Ay+fdTfX8ocqUQqV6GF2rHe5C4n7Bohqap75kFOX9KjUVrbrO6xuQ2xllxjAM6IFbxUrHKtrh/6aOQLeNIZHDXPb+gV6hCtx6jJnnfNMwQJh4eGw+vbTNJdubohfvkfTzQHmUpzHoYNn+adRQ5E4NtMNTBdexYXy+vZ30dBsnsQiGx3/34yStvZK4y0tbB0TM6h35spvUYRygW00VcD6gCTmEWcF8bwCrUtXIrYExF4qHQrxZz7YqUmffrMAAA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=hA5qmvYL3p1q4e3g3ow+pZKiWpUAb6Bo4DPYbGBLqQk=; b=tWY8aHK3fG4dsLmCIwnUF0fUCMlhST2b0yyaVMjdW13q8Y0pDXfSx4FV6DoWHfAUuOcpC846y8kMKNfN43LDlwVtPfiSs8PK1GBbmqGyKPTyNXGkFXmhdEN5918swu6yrM+QGhncF5IK6r0S7ZfSUXf8JUPGWdjn420hChku5A7qaHCD/WUTcgZeHzuoX0cLAXIMGxVRc83UQZU73YgXUT33fMNDH5rbeTtkOnQ86Vb8I25hOIdgkEtGLvSCxzjVLtBKZBjmmW9tUpHR8TqG0NK8xLyaAOX5Ldw23vhqG6Hk+jN+GbMBLUggSD5G1MAYbHisoWiqyfpnnJgbrHxeNQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 172.205.89.229) smtp.rcpttodomain=gcc.gnu.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=arm.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=hA5qmvYL3p1q4e3g3ow+pZKiWpUAb6Bo4DPYbGBLqQk=; b=sGwT4SNkgjcxcCpccUWbH0l+J4M6Pwa21EMFr8M6P+xvMqaIVc9Xlq6LxFdhexVYheRvsBwSU9rrADs+3v72DIwZKXkCGLMOhalkdAc1Sr8LgPHXeEV3pt+C78lxuEb6Kag3fijPDeXbocCFAkiZE9hU3R3MC7HdjmrRd/JW898= Received: from AM4PR07CA0025.eurprd07.prod.outlook.com (2603:10a6:205:1::38) by PAWPR08MB9966.eurprd08.prod.outlook.com (2603:10a6:102:35e::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.13; Wed, 17 Sep 2025 12:45:42 +0000 Received: from AM3PEPF0000A796.eurprd04.prod.outlook.com (2603:10a6:205:1:cafe::4b) by AM4PR07CA0025.outlook.office365.com (2603:10a6:205:1::38) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.10 via Frontend Transport; Wed, 17 Sep 2025 12:45:47 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 172.205.89.229) smtp.mailfrom=arm.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 172.205.89.229 as permitted sender) receiver=protection.outlook.com; client-ip=172.205.89.229; helo=nebula.arm.com; pr=C Received: from nebula.arm.com (172.205.89.229) by AM3PEPF0000A796.mail.protection.outlook.com (10.167.16.101) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.9137.12 via Frontend Transport; Wed, 17 Sep 2025 12:45:42 +0000 Received: from AZ-NEU-EX05.Arm.com (10.240.25.133) by AZ-NEU-EX06.Arm.com (10.240.25.134) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Wed, 17 Sep 2025 12:44:58 +0000 Received: from ip-10-248-139-135.eu-west-1.compute.internal (10.248.139.135) by mail.arm.com (10.240.25.133) with Microsoft SMTP Server id 15.1.2507.39 via Frontend Transport; Wed, 17 Sep 2025 12:44:58 +0000 From: To: , CC: , , , , , , , , , , , , , Alfie Richards Subject: [PATCH v11 02/13] x86: fmv: Refactor FMV name mangling. Date: Wed, 17 Sep 2025 12:44:53 +0000 Message-ID: <20250917124456.170437-2-alfie.richards@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250917124456.170437-1-alfie.richards@arm.com> References: <20250917124456.170437-1-alfie.richards@arm.com> MIME-Version: 1.0 X-EOPAttributedMessage: 1 X-MS-TrafficTypeDiagnostic: AM3PEPF0000A796:EE_|PAWPR08MB9966:EE_|AMS0EPF00000191:EE_|DB9PR08MB6443:EE_ X-MS-Office365-Filtering-Correlation-Id: 70d01837-ea47-4a2c-0a20-08ddf5e83082 x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; ARA:13230040|1800799024|7416014|376014|36860700013|82310400026; X-Microsoft-Antispam-Message-Info-Original: 7r6GMQwgTSy3xSal1l0I1GzDENTwLym4utP666JARIE/CZQY8pWSzO0ByAKXVOT9J1xU+M0rh51tErR9MX0Ad61ELI+E/4UAgeWK7Q1ZBJpX6sZfTTj5FudeF9pTeVtMe8PrWIO7UbX+PAeI1LYhGGXHXlXxdd4FV3xxtRNbiTZQ4e0f3nScf4jS2jQLtxL4jhLO3e15PT4z0BUgHckjG6P65AJWXo06Jd7ggiI3cePuA3ysYgLMFHhjJtYqQj3ETH1a8I0QFUqdjEXyS4ji6EhNOFP7IWv/ASNkKEc/W/nquRKh9DZbz+qnAVPhcF2ASZZu/AxrTD9fRsT/fGwiXsy2QRn7ibk+lqKQVs92SoGxtKjLyHfxFLHSplzdKybZxm3+8tSWMMa0xMJ3NGBkS4Alkvnj5VPV12DnI3EHZZorisguhvAi1tJ6xZXtw/HV+QGMklQamVfV/Hwn6IlXfjKXvkwTWilIHWLNFev2Yvfjr3vESyK162yQ1ldiSaRnZd/G5HUUOOtvjdlM8nTfkfdvj12jZGBT9JS48ZJ2teOrG7g+5/49mzBDYwk/5A6/GvObikJqRMpw1tIPaozuaYX26ypkQPmOAIH4VXb0vGflZWOuzF0iP62FLdnaS8YGHHS8ojvawMnWaRCG8cwDN0WaLQvAQCqrCCFjmjVcVvYj1KCt69AGrgFU/rhMn0hVyhW7TNlrXaGphanDwUOXb53LJVdcC41cOgidxg6Kj7jbeYozV/azWW9SYQnAZWe2YtqqkYfe0Ynuhj/sy/VGJgYy3CBjXjfoK5ptrPd6GAJ0tUYmRwoUL9lStWalQe4Aq5Y1FAUfx/WIL5Z9pQPFIuB/YsN/KdQvqYojaEpABrxaDk1jS76k4081wAbs6S2aTPeAbogHnb0rzV58CArWdqf6WN2udLFd77+8bCaVEt+IqII7cNwYAgJgn+uL1R2DH/WSXIidUNqXw14frV6q9tloNtS96D55NtRx+dXiLYsezYArN762J81eMzL2gVf2O1E87XJJCoU9ZTBvOx+EYKt9p63vuLTLExjsRM21uAI5o5N92ZK/gQPF32udUO6iH+vBQYRbZXd5T+jVfHvtyRdl94EKHxe0C2acOYDNl8E+63ubMIw/zOrEn3MsHIeODg08M/lo/H1mhS3E/O/43KThP+bME9VbT+aqTbfDsIuZZ2KalQVZ7JZH8GdDbXFv1GHwAr3Z6uphsqHobCBSXNuJ5XHra7I44XKgNB/uIBB5fm8DCjSSmpWqbkG1TkKSFZgA11WoY1LuKqQptCn+fdvyUsEtGg6UMWym6x7DlRJMmu9cO40/lcD5ZX90ZIbdAYlJbXhLzknME4Vj/psW4GmPpZks5ZJGBT3qP3+n5iBGXxzJ7hRgyZADottNzPT30OGvkNt9399XaUX0YHJ8HmEVObl0/F/NlheCUW+m2589TAVuDBLGQGlgzqq3hWS0ANyZXGBjVoOifdFvGtU4un+etzdKnvjNE/Hc8+/0Btu70gyK6zj8QIhuv53spw+K X-Forefront-Antispam-Report-Untrusted: CIP:172.205.89.229; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:nebula.arm.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230040)(1800799024)(7416014)(376014)(36860700013)(82310400026); DIR:OUT; SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAWPR08MB9966 X-MS-Exchange-Transport-CrossTenantHeadersStripped: AMS0EPF00000191.eurprd05.prod.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: f6857552-e14d-4e77-8018-08ddf5e81ce8 X-Microsoft-Antispam: BCL:0; ARA:13230040|1800799024|36860700013|7416014|376014|82310400026|35042699022|14060799003; X-Microsoft-Antispam-Message-Info: iYJti+n94sMWb5pibvSxYQfYHhyCFHezFB/TzASv2dS0oHyqHQV7lXxuQkBqmjgieVIBG6WfiOO5puawjcEUE/2FhP1MCU+pWIRL11JK6T6X5pEykIFAXfdTn774dnemGCuV+Iut35urpuCGEd2jdmkPoqU9+gwQm5FlTJHNPhbHhqffDusc0XO9FwdfXViJ9ZHczYd1KOEMhFM9vy1afXP5i7Fpg1Zq9uZl9QPR0Wb4B6atQftSArzawPwybrbzUm8BuKLb9JGlLcMoxGwZ4NqK1PAsKZAtni2NePKn5RQ24A8XtEzLAvM9KpnLbvpLxyvnV7vPLUBjwGunsHQH1QfOvnovMo+bfdFSFFdA1XMn0WlnPD9B/t+LOqzELxEIHm/ATeGrfW6oIPADW//KqXt/vrHbEYkWSqc1nEPiLhNOmzYThyYvPRh66zVW1lQDJwoWpsPVHu3GDK+AFjHzR8rvMvaFyZUeo6dGNg7n7T/Dy+vzRIrbaevSr1ErgINwwPpcxpbTaTENeqLUhLy3FPbXmsoKc/C+41o4sMGRvOjAFD63MDzopgNri1K1vNCG55/xm58HUH4BNxm0ae6qJ3VBmvn61vz+02olnKPmJ9hcJ9ysfYwRlIY0afVbQv1qGhFISLDgtfcj7MFGi6Y7Cn+Opp8WPiPgSY2/9949tQ4Gulcap9RtzECTgCb9qDfAtMZqBKh6k2ngEvYUnqZg5tKl9qdHVu70ONdbszQyVWGyLRpBsaQ+tGxcfGFxOrOaMIIf5CnCrNoIs53dk+oONoCAyKO+Lc1aNrPdW4ZYRu7UN0KJqKRoO8/A6LiJJ9QtKyFd3z8tfsL6/6rFukJ+sTUVeyj3UXLQPOTfOnbU+5xcNJAm9hzd4dYCf8sRsDv9T18V/aeauovLcIthmXFQWVi9lxQHLq9pq3NS3B6sm+BbqV7zIcQaZW7YQeEWpMS5rkugNJvDc4Pjv7z2I0xeNpQedFjtRFVA1YGCUGmt2yCO1e7vyWmp4+GLmMu2t0MBPH6rnXGCspNb3QeUaBvKfVTFE/AX5ZDBekUq1wnZjN4/TVkpwhYd+/dxF+tIWKMVbLa+OeeSCJt8lp6zaD5WJQ2KycfXUI3ZUDqc97bwETwVOqzwztcXkJM4rA7tyPFfrxF87RSxwolwwSU6RBBBF+fq79Tl418egyZBAzXnjVeABVFyGL3YFl+Ib4CIjrBo/s3WCZpLHIV+VcCd3VKFWNQeA7TcLTq/D6trMvNKtKzjea3+phwh+QW9C0od12LbQunYxOSCcltQ3Gsab0+V+CaOPkJ+WnGAd4Xszs/A2z5dyqfO6WetyJ2DJANMcGKvinpko6Bu2XcuuGAPtTmP2+xQpAToshi/VGQ62JsmUMMjaDIDtHTTViXXRjPL4d0+uBccwv4zb8xKEmqtU6uyesV7K0Os6o179qcx3DJKugdKN2xNlpZTI3oUEtMhb2C921J/M+o17QewjxdcLdAhxAoZGaEZqU9BOuHgFm1YiDLh7h91KjZ9gGFOiO4bvROp X-Forefront-Antispam-Report: CIP:4.158.2.129; CTRY:GB; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:outbound-uk1.az.dlp.m.darktrace.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230040)(1800799024)(36860700013)(7416014)(376014)(82310400026)(35042699022)(14060799003); DIR:OUT; SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Sep 2025 12:46:15.0482 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 70d01837-ea47-4a2c-0a20-08ddf5e83082 X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[4.158.2.129]; Helo=[outbound-uk1.az.dlp.m.darktrace.com] X-MS-Exchange-CrossTenant-AuthSource: AMS0EPF00000191.eurprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR08MB6443 X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FORGED_SPF_HELO, GIT_PATCH_0, RCVD_IN_MSPIKE_H2, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_PASS, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org From: Alfie Richards This patch is an overhaul of how FMV name mangling works. Previously mangling logic was duplicated in several places across both target specific and independent code. This patch changes this such that all mangling is done in targetm.mangle_decl_assembler_name (including for the dispatched symbol and dispatcher resolver). Adds the assembler_name member to cgraph_function_version_info to store the base assembler name of the function set, before FMV mangling. This allows for the removing of previous hacks, such as where the default mangled decl's assembler name was unmangled to then remangle all versions and the resolver and dispatched symbol. This introduces a change (shown in test changes) for the assembler name of the dispatched symbol for a x86 versioned function set. Previously it used the function name mangled twice. This was hard to reproduce without hacks I wasn't comfortable with. Therefore, the mangling is changed to instead append ".ifunc" which matches clang's behavior. This change also refactors expand_target_clone using targetm.mangle_decl_assembler_name for mangling and get_clone_versions. It is modified such that if the target_clone is in a FMV structure the ordering is preserved once expanded. This is used later for ACLE semantics and target_clone/target_version mixing. gcc/ChangeLog: * attribs.cc (make_dispatcher_decl): Move duplicated cgraph logic into this function and change to use targetm.mangle_decl_assembler_name for mangling. * cgraph.cc (cgraph_node::insert_new_function_version): Record assembler_name. * cgraph.h (struct cgraph_function_version_info): Add assembler_name. (struct cgraph_node): Add dispatcher_resolver_function and is_target_clone. * config/aarch64/aarch64.cc (aarch64_parse_fmv_features): Change to support string_slice. (aarch64_process_target_version_attr): Ditto. (get_feature_mask_for_version): Ditto. (aarch64_mangle_decl_assembler_name): Add logic for mangling dispatched symbol and resolver. (get_suffixed_assembler_name): Removed. (make_resolver_func): Refactor to use aarch64_mangle_decl_assembler_name for mangling. (aarch64_generate_version_dispatcher_body): Remove remangling. (aarch64_get_function_versions_dispatcher): Refactor to remove duplicated cgraph logic. * config/i386/i386-features.cc (ix86_mangle_function_version_assembler_name): Refactor to use clone_identifier and to mangle default. (ix86_mangle_decl_assembler_name): Add logic for mangling dispatched symbol and resolver. (ix86_get_function_versions_dispatcher): Remove duplicated cgraph logic. (make_resolver_func): Refactor to use ix86_mangle_decl_assembler_name for mangling. * config/riscv/riscv.cc (riscv_mangle_decl_assembler_name): Add logic for FMV mangling. (get_suffixed_assembler_name): Removed. (make_resolver_func): Refactor to use riscv_mangle_decl_assembler_name for mangling. (riscv_generate_version_dispatcher_body): Remove unnecessary remangling. (riscv_get_function_versions_dispatcher): Remove duplicated cgraph logic. * config/rs6000/rs6000.cc (rs6000_mangle_decl_assembler_name): New function. (rs6000_get_function_versions_dispatcher): Remove duplicated cgraph logic. (make_resolver_func): Refactor to use rs6000_mangle_decl_assembler_name for mangling. (rs6000_mangle_function_version_assembler_name): New function. * multiple_target.cc (create_dispatcher_calls): Remove mangling code. (get_attr_str): Removed. (separate_attrs): Ditto. (is_valid_asm_symbol): Removed. (create_new_asm_name): Ditto. (expand_target_clones): Refactor to use targetm.mangle_decl_assembler_name for mangling and be more general. * tree.cc (get_target_clone_attr_len): Removed. * tree.h (get_target_clone_attr_len): Removed. gcc/cp/ChangeLog: * decl.cc (maybe_mark_function_versioned): Change to insert function version and therefore record assembler name. gcc/testsuite/ChangeLog: * g++.target/i386/mv-symbols1.C: Update x86 FMV mangling. * g++.target/i386/mv-symbols3.C: Ditto. * g++.target/i386/mv-symbols4.C: Ditto. * g++.target/i386/mv-symbols5.C: Ditto. --- gcc/attribs.cc | 45 +++- gcc/cgraph.cc | 1 + gcc/cgraph.h | 13 +- gcc/config/aarch64/aarch64.cc | 167 +++++-------- gcc/config/i386/i386-features.cc | 74 +++--- gcc/config/riscv/riscv.cc | 110 +++------ gcc/config/rs6000/rs6000.cc | 82 +++++-- gcc/cp/decl.cc | 7 + gcc/multiple_target.cc | 250 ++++++-------------- gcc/testsuite/g++.target/i386/mv-symbols1.C | 12 +- gcc/testsuite/g++.target/i386/mv-symbols3.C | 10 +- gcc/testsuite/g++.target/i386/mv-symbols4.C | 10 +- gcc/testsuite/g++.target/i386/mv-symbols5.C | 10 +- gcc/tree.cc | 26 -- gcc/tree.h | 2 - 15 files changed, 348 insertions(+), 471 deletions(-) diff --git a/gcc/attribs.cc b/gcc/attribs.cc index 3fce9d62525..c75fd1371fd 100644 --- a/gcc/attribs.cc +++ b/gcc/attribs.cc @@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-pretty-print.h" #include "intl.h" #include "gcc-urlifier.h" +#include "cgraph.h" /* Table of the tables of attributes (common, language, format, machine) searched. */ @@ -1248,18 +1249,12 @@ common_function_versions (tree fn1, tree fn2) tree make_dispatcher_decl (const tree decl) { - tree func_decl; - char *func_name; - tree fn_type, func_type; + tree fn_type = TREE_TYPE (decl); + tree func_type = build_function_type (TREE_TYPE (fn_type), + TYPE_ARG_TYPES (fn_type)); + tree func_decl = build_fn_decl (IDENTIFIER_POINTER (DECL_NAME (decl)), + func_type); - func_name = xstrdup (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); - - fn_type = TREE_TYPE (decl); - func_type = build_function_type (TREE_TYPE (fn_type), - TYPE_ARG_TYPES (fn_type)); - - func_decl = build_fn_decl (func_name, func_type); - XDELETEVEC (func_name); TREE_USED (func_decl) = 1; DECL_CONTEXT (func_decl) = NULL_TREE; DECL_INITIAL (func_decl) = error_mark_node; @@ -1269,6 +1264,34 @@ make_dispatcher_decl (const tree decl) DECL_EXTERNAL (func_decl) = 1; /* This will be of type IFUNCs have to be externally visible. */ TREE_PUBLIC (func_decl) = 1; + TREE_NOTHROW (func_decl) = TREE_NOTHROW (decl); + + /* Set the decl name to avoid graph_node re-mangling it. */ + SET_DECL_ASSEMBLER_NAME (func_decl, DECL_ASSEMBLER_NAME (decl)); + + cgraph_node *node = cgraph_node::get (decl); + gcc_assert (node); + cgraph_function_version_info *node_v = node->function_version (); + gcc_assert (node_v); + + /* Set flags on the cgraph_node for the new decl. */ + cgraph_node *func_node = cgraph_node::get_create (func_decl); + func_node->dispatcher_function = true; + func_node->definition = true; + + cgraph_function_version_info *func_v + = func_node->insert_new_function_version (); + func_v->next = node_v; + func_v->assembler_name = node_v->assembler_name; + + /* If the default node is from a target_clone, mark the dispatcher as from + target_clone. */ + func_node->is_target_clone = node->is_target_clone; + + /* Get the assembler name by mangling with the base assembler name. */ + tree id = targetm.mangle_decl_assembler_name + (func_decl, func_v->assembler_name); + symtab->change_decl_assembler_name (func_decl, id); return func_decl; } diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc index 32071a84bac..c0be16edfcb 100644 --- a/gcc/cgraph.cc +++ b/gcc/cgraph.cc @@ -322,6 +322,7 @@ cgraph_node::insert_new_function_version (void) version_info_node = NULL; version_info_node = ggc_cleared_alloc (); version_info_node->this_node = this; + version_info_node->assembler_name = DECL_ASSEMBLER_NAME (this->decl); if (cgraph_fnver_htab == NULL) cgraph_fnver_htab = hash_table::create_ggc (2); diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 189fa74497b..21f89112769 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -856,6 +856,9 @@ struct GTY((for_user)) cgraph_function_version_info { dispatcher. The dispatcher decl is an alias to the resolver function decl. */ tree dispatcher_resolver; + + /* The assmbly name of the function set before version mangling. */ + tree assembler_name; }; #define DEFCIFCODE(code, type, string) CIF_ ## code, @@ -904,7 +907,9 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node used_as_abstract_origin (false), lowered (false), process (false), frequency (NODE_FREQUENCY_NORMAL), only_called_at_startup (false), only_called_at_exit (false), - tm_clone (false), dispatcher_function (false), calls_comdat_local (false), + tm_clone (false), dispatcher_function (false), + dispatcher_resolver_function (false), is_target_clone (false), + calls_comdat_local (false), icf_merged (false), nonfreeing_fn (false), merged_comdat (false), merged_extern_inline (false), parallelized_function (false), split_part (false), indirect_call_target (false), local (false), @@ -1482,6 +1487,12 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node unsigned tm_clone : 1; /* True if this decl is a dispatcher for function versions. */ unsigned dispatcher_function : 1; + /* True if this decl is a resolver for function versions. */ + unsigned dispatcher_resolver_function : 1; + /* True this is part of a multiversioned set and this version comes from a + target_clone attribute. Or if this is a dispatched symbol or resolver + and the default version comes from a target_clones. */ + unsigned is_target_clone : 1; /* True if this decl calls a COMDAT-local function. This is set up in compute_fn_summary and inline_call. */ unsigned calls_comdat_local : 1; diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index ef9c16598c0..c056fec293a 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -20382,7 +20382,7 @@ static aarch64_fmv_feature_datum aarch64_fmv_feature_data[] = { #include "config/aarch64/aarch64-option-extensions.def" }; -/* Parse a function multiversioning feature string STR, as found in a +/* Parse a function multiversioning feature string_slice STR, as found in a target_version or target_clones attribute. If ISA_FLAGS is nonnull, then update it with the specified architecture @@ -20394,37 +20394,34 @@ static aarch64_fmv_feature_datum aarch64_fmv_feature_data[] = { the extension string is created and stored to INVALID_EXTENSION. */ static enum aarch_parse_opt_result -aarch64_parse_fmv_features (const char *str, aarch64_feature_flags *isa_flags, +aarch64_parse_fmv_features (string_slice str, aarch64_feature_flags *isa_flags, aarch64_fmv_feature_mask *feature_mask, std::string *invalid_extension) { if (feature_mask) *feature_mask = 0ULL; - if (strcmp (str, "default") == 0) + if (str == "default") return AARCH_PARSE_OK; - while (str != NULL && *str != 0) + gcc_assert (str.is_valid ()); + + while (str.is_valid ()) { - const char *ext; - size_t len; + string_slice ext; - ext = strchr (str, '+'); + ext = string_slice::tokenize (&str, "+"); - if (ext != NULL) - len = ext - str; - else - len = strlen (str); + gcc_assert (ext.is_valid ()); - if (len == 0) + if (!ext.is_valid () || ext.empty ()) return AARCH_PARSE_MISSING_ARG; int num_features = ARRAY_SIZE (aarch64_fmv_feature_data); int i; for (i = 0; i < num_features; i++) { - if (strlen (aarch64_fmv_feature_data[i].name) == len - && strncmp (aarch64_fmv_feature_data[i].name, str, len) == 0) + if (aarch64_fmv_feature_data[i].name == ext) { if (isa_flags) *isa_flags |= aarch64_fmv_feature_data[i].opt_flags; @@ -20436,7 +20433,8 @@ aarch64_parse_fmv_features (const char *str, aarch64_feature_flags *isa_flags, { /* Duplicate feature. */ if (invalid_extension) - *invalid_extension = std::string (str, len); + *invalid_extension + = std::string (ext.begin (), ext.size ()); return AARCH_PARSE_DUPLICATE_FEATURE; } } @@ -20448,14 +20446,9 @@ aarch64_parse_fmv_features (const char *str, aarch64_feature_flags *isa_flags, { /* Feature not found in list. */ if (invalid_extension) - *invalid_extension = std::string (str, len); + *invalid_extension = std::string (ext.begin (), ext.size ()); return AARCH_PARSE_INVALID_FEATURE; } - - str = ext; - if (str) - /* Skip over the next '+'. */ - str++; } return AARCH_PARSE_OK; @@ -20492,7 +20485,7 @@ aarch64_process_target_version_attr (tree args) return false; } - const char *str = TREE_STRING_POINTER (args); + string_slice str = TREE_STRING_POINTER (args); enum aarch_parse_opt_result parse_res; auto isa_flags = aarch64_asm_isa_flags; @@ -20516,13 +20509,13 @@ aarch64_process_target_version_attr (tree args) case AARCH_PARSE_INVALID_FEATURE: error ("invalid feature modifier %qs of value %qs in " "% attribute", invalid_extension.c_str (), - str); + TREE_STRING_POINTER (args)); break; case AARCH_PARSE_DUPLICATE_FEATURE: error ("duplicate feature modifier %qs of value %qs in " "% attribute", invalid_extension.c_str (), - str); + TREE_STRING_POINTER (args)); break; default: @@ -20594,13 +20587,14 @@ get_feature_mask_for_version (tree decl) if (version_attr == NULL) return 0; - const char *version_string = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE - (version_attr))); + string_slice version_string + = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (version_attr))); + enum aarch_parse_opt_result parse_res; aarch64_fmv_feature_mask feature_mask; - parse_res = aarch64_parse_fmv_features (version_string, NULL, &feature_mask, - NULL); + parse_res = aarch64_parse_fmv_features (version_string, NULL, + &feature_mask, NULL); /* We should have detected any errors before getting here. */ gcc_assert (parse_res == AARCH_PARSE_OK); @@ -20707,56 +20701,37 @@ tree aarch64_mangle_decl_assembler_name (tree decl, tree id) { /* For function version, add the target suffix to the assembler name. */ - if (TREE_CODE (decl) == FUNCTION_DECL - && DECL_FUNCTION_VERSIONED (decl)) + if (TREE_CODE (decl) == FUNCTION_DECL) { - aarch64_fmv_feature_mask feature_mask = get_feature_mask_for_version (decl); - - std::string name = IDENTIFIER_POINTER (id); - - /* For the default version, append ".default". */ - if (feature_mask == 0ULL) + cgraph_node *node = cgraph_node::get (decl); + if (node && node->dispatcher_function) + return id; + else if (node && node->dispatcher_resolver_function) + return clone_identifier (id, "resolver"); + else if (DECL_FUNCTION_VERSIONED (decl)) { - name += ".default"; - return get_identifier (name.c_str()); - } + aarch64_fmv_feature_mask feature_mask + = get_feature_mask_for_version (decl); - name += "._"; + if (feature_mask == 0ULL) + return clone_identifier (id, "default"); - int num_features = ARRAY_SIZE (aarch64_fmv_feature_data); - for (int i = 0; i < num_features; i++) - { - if (feature_mask & aarch64_fmv_feature_data[i].feature_mask) - { - name += "M"; - name += aarch64_fmv_feature_data[i].name; - } - } + std::string suffix = "_"; - if (DECL_ASSEMBLER_NAME_SET_P (decl)) - SET_DECL_RTL (decl, NULL); + int num_features = ARRAY_SIZE (aarch64_fmv_feature_data); + for (int i = 0; i < num_features; i++) + if (feature_mask & aarch64_fmv_feature_data[i].feature_mask) + { + suffix += "M"; + suffix += aarch64_fmv_feature_data[i].name; + } - id = get_identifier (name.c_str()); + id = clone_identifier (id, suffix.c_str (), true); + } } return id; } -/* Return an identifier for the base assembler name of a versioned function. - This is computed by taking the default version's assembler name, and - stripping off the ".default" suffix if it's already been appended. */ - -static tree -get_suffixed_assembler_name (tree default_decl, const char *suffix) -{ - std::string name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (default_decl)); - - auto size = name.size (); - if (size >= 8 && name.compare (size - 8, 8, ".default") == 0) - name.resize (size - 8); - name += suffix; - return get_identifier (name.c_str()); -} - /* Make the resolver function decl to dispatch the versions of a multi-versioned function, DEFAULT_DECL. IFUNC_ALIAS_DECL is ifunc alias that will point to the created resolver. Create an @@ -20770,11 +20745,6 @@ make_resolver_func (const tree default_decl, { tree decl, type, t; - /* Create resolver function name based on default_decl. We need to remove an - existing ".default" suffix if this has already been appended. */ - tree decl_name = get_suffixed_assembler_name (default_decl, ".resolver"); - const char *resolver_name = IDENTIFIER_POINTER (decl_name); - /* The resolver function should have signature (void *) resolver (uint64_t, const __ifunc_arg_t *) */ type = build_function_type_list (ptr_type_node, @@ -20782,10 +20752,21 @@ make_resolver_func (const tree default_decl, build_ifunc_arg_type (), NULL_TREE); - decl = build_fn_decl (resolver_name, type); - SET_DECL_ASSEMBLER_NAME (decl, decl_name); + cgraph_node *node = cgraph_node::get (default_decl); + gcc_assert (node && node->function_version ()); + + decl = build_fn_decl (IDENTIFIER_POINTER (DECL_NAME (default_decl)), type); + + /* Set the assembler name to prevent cgraph_node attempting to mangle. */ + SET_DECL_ASSEMBLER_NAME (decl, DECL_ASSEMBLER_NAME (default_decl)); + + cgraph_node *resolver_node = cgraph_node::get_create (decl); + resolver_node->dispatcher_resolver_function = true; + + tree id = aarch64_mangle_decl_assembler_name + (decl, node->function_version ()->assembler_name); + symtab->change_decl_assembler_name (decl, id); - DECL_NAME (decl) = decl_name; TREE_USED (decl) = 1; DECL_ARTIFICIAL (decl) = 1; DECL_IGNORED_P (decl) = 1; @@ -20850,7 +20831,7 @@ make_resolver_func (const tree default_decl, gcc_assert (ifunc_alias_decl != NULL); /* Mark ifunc_alias_decl as "ifunc" with resolver as resolver_name. */ DECL_ATTRIBUTES (ifunc_alias_decl) - = make_attribute ("ifunc", resolver_name, + = make_attribute ("ifunc", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), DECL_ATTRIBUTES (ifunc_alias_decl)); /* Create the alias for dispatch to resolver here. */ @@ -21127,27 +21108,6 @@ aarch64_generate_version_dispatcher_body (void *node_p) cgraph_edge::rebuild_edges (); pop_cfun (); - /* Fix up symbol names. First we need to obtain the base name, which may - have already been mangled. */ - tree base_name = get_suffixed_assembler_name (default_ver_decl, ""); - - /* We need to redo the version mangling on the non-default versions for the - target_clones case. Redoing the mangling for the target_version case is - redundant but does no harm. We need to skip the default version, because - expand_clones will append ".default" later; fortunately that suffix is the - one we want anyway. */ - for (versn_info = node_version_info->next->next; versn_info; - versn_info = versn_info->next) - { - tree version_decl = versn_info->this_node->decl; - tree name = aarch64_mangle_decl_assembler_name (version_decl, - base_name); - symtab->change_decl_assembler_name (version_decl, name); - } - - /* We also need to use the base name for the ifunc declaration. */ - symtab->change_decl_assembler_name (node->decl, base_name); - return resolver_decl; } @@ -21191,20 +21151,9 @@ aarch64_get_function_versions_dispatcher (void *decl) if (targetm.has_ifunc_p ()) { struct cgraph_function_version_info *it_v = NULL; - struct cgraph_node *dispatcher_node = NULL; - struct cgraph_function_version_info *dispatcher_version_info = NULL; /* Right now, the dispatching is done via ifunc. */ dispatch_decl = make_dispatcher_decl (default_node->decl); - TREE_NOTHROW (dispatch_decl) = TREE_NOTHROW (fn); - - dispatcher_node = cgraph_node::get_create (dispatch_decl); - gcc_assert (dispatcher_node != NULL); - dispatcher_node->dispatcher_function = 1; - dispatcher_version_info - = dispatcher_node->insert_new_function_version (); - dispatcher_version_info->next = default_version_info; - dispatcher_node->definition = 1; /* Set the dispatcher for all the versions. */ it_v = default_version_info; diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc index 0608dd2f9ac..c313fb85f9b 100644 --- a/gcc/config/i386/i386-features.cc +++ b/gcc/config/i386/i386-features.cc @@ -5299,8 +5299,7 @@ static tree ix86_mangle_function_version_assembler_name (tree decl, tree id) { tree version_attr; - const char *orig_name, *version_string; - char *attr_str, *assembler_name; + char *attr_str; if (DECL_DECLARED_INLINE_P (decl) && lookup_attribute ("gnu_inline", @@ -5318,25 +5317,16 @@ ix86_mangle_function_version_assembler_name (tree decl, tree id) /* target attribute string cannot be NULL. */ gcc_assert (version_attr != NULL_TREE); - orig_name = IDENTIFIER_POINTER (id); - version_string - = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (version_attr))); - - if (strcmp (version_string, "default") == 0) - return id; - attr_str = sorted_attr_string (TREE_VALUE (version_attr)); - assembler_name = XNEWVEC (char, strlen (orig_name) + strlen (attr_str) + 2); - - sprintf (assembler_name, "%s.%s", orig_name, attr_str); /* Allow assembler name to be modified if already set. */ if (DECL_ASSEMBLER_NAME_SET_P (decl)) SET_DECL_RTL (decl, NULL); - tree ret = get_identifier (assembler_name); + tree ret = clone_identifier (id, attr_str, true); + XDELETEVEC (attr_str); - XDELETEVEC (assembler_name); + return ret; } @@ -5344,9 +5334,21 @@ tree ix86_mangle_decl_assembler_name (tree decl, tree id) { /* For function version, add the target suffix to the assembler name. */ - if (TREE_CODE (decl) == FUNCTION_DECL - && DECL_FUNCTION_VERSIONED (decl)) - id = ix86_mangle_function_version_assembler_name (decl, id); + if (TREE_CODE (decl) == FUNCTION_DECL) + { + cgraph_node *node = cgraph_node::get (decl); + /* Mangle all versions when annotated with target_clones, but only + non-default versions when annotated with target attributes. */ + if (DECL_FUNCTION_VERSIONED (decl) + && (node->is_target_clone + || !is_function_default_version (node->decl))) + id = ix86_mangle_function_version_assembler_name (decl, id); + /* Mangle the dispatched symbol but only in the case of target clones. */ + else if (node && node->dispatcher_function && !node->is_target_clone) + id = clone_identifier (id, "ifunc"); + else if (node && node->dispatcher_resolver_function) + id = clone_identifier (id, "resolver"); + } #ifdef SUBTARGET_MANGLE_DECL_ASSEMBLER_NAME id = SUBTARGET_MANGLE_DECL_ASSEMBLER_NAME (decl, id); #endif @@ -5395,20 +5397,9 @@ ix86_get_function_versions_dispatcher (void *decl) if (targetm.has_ifunc_p ()) { struct cgraph_function_version_info *it_v = NULL; - struct cgraph_node *dispatcher_node = NULL; - struct cgraph_function_version_info *dispatcher_version_info = NULL; /* Right now, the dispatching is done via ifunc. */ dispatch_decl = make_dispatcher_decl (default_node->decl); - TREE_NOTHROW (dispatch_decl) = TREE_NOTHROW (fn); - - dispatcher_node = cgraph_node::get_create (dispatch_decl); - gcc_assert (dispatcher_node != NULL); - dispatcher_node->dispatcher_function = 1; - dispatcher_version_info - = dispatcher_node->insert_new_function_version (); - dispatcher_version_info->next = default_version_info; - dispatcher_node->definition = 1; /* Set the dispatcher for all the versions. */ it_v = default_version_info; @@ -5442,17 +5433,28 @@ make_resolver_func (const tree default_decl, { tree decl, type, t; - /* Create resolver function name based on default_decl. */ - tree decl_name = clone_function_name (default_decl, "resolver"); - const char *resolver_name = IDENTIFIER_POINTER (decl_name); - /* The resolver function should return a (void *). */ type = build_function_type_list (ptr_type_node, NULL_TREE); - decl = build_fn_decl (resolver_name, type); - SET_DECL_ASSEMBLER_NAME (decl, decl_name); + cgraph_node *node = cgraph_node::get (default_decl); + gcc_assert (node && node->function_version ()); + + decl = build_fn_decl (IDENTIFIER_POINTER (DECL_NAME (default_decl)), type); + + /* Set the assembler name to prevent cgraph_node attempting to mangle. */ + SET_DECL_ASSEMBLER_NAME (decl, DECL_ASSEMBLER_NAME (default_decl)); + + cgraph_node *resolver_node = cgraph_node::get_create (decl); + resolver_node->dispatcher_resolver_function = true; + + if (node->is_target_clone) + resolver_node->is_target_clone = true; + + tree id = ix86_mangle_decl_assembler_name + (decl, node->function_version ()->assembler_name); + SET_DECL_ASSEMBLER_NAME (decl, id); - DECL_NAME (decl) = decl_name; + DECL_NAME (decl) = DECL_NAME (default_decl); TREE_USED (decl) = 1; DECL_ARTIFICIAL (decl) = 1; DECL_IGNORED_P (decl) = 1; @@ -5499,7 +5501,7 @@ make_resolver_func (const tree default_decl, gcc_assert (ifunc_alias_decl != NULL); /* Mark ifunc_alias_decl as "ifunc" with resolver as resolver_name. */ DECL_ATTRIBUTES (ifunc_alias_decl) - = make_attribute ("ifunc", resolver_name, + = make_attribute ("ifunc", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), DECL_ATTRIBUTES (ifunc_alias_decl)); /* Create the alias for dispatch to resolver here. */ diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index b93103616b8..4bab21bee70 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -14127,32 +14127,31 @@ tree riscv_mangle_decl_assembler_name (tree decl, tree id) { /* For function version, add the target suffix to the assembler name. */ - if (TREE_CODE (decl) == FUNCTION_DECL - && DECL_FUNCTION_VERSIONED (decl)) + if (TREE_CODE (decl) == FUNCTION_DECL) { - std::string name = IDENTIFIER_POINTER (id) + std::string ("."); - tree target_attr = lookup_attribute ("target_version", - DECL_ATTRIBUTES (decl)); - - if (target_attr == NULL_TREE) + cgraph_node *node = cgraph_node::get (decl); + if (node && node->dispatcher_resolver_function) + return clone_identifier (id, "resolver"); + else if (DECL_FUNCTION_VERSIONED (decl)) { - name += "default"; - return get_identifier (name.c_str ()); - } + tree target_attr + = lookup_attribute ("target_version", DECL_ATTRIBUTES (decl)); - const char *version_string = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE - (target_attr))); + if (target_attr == NULL_TREE) + return clone_identifier (id, "default"); - /* Replace non-alphanumeric characters with underscores as the suffix. */ - for (const char *c = version_string; *c; c++) - name += ISALNUM (*c) == 0 ? '_' : *c; + const char *version_string + = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (target_attr))); - if (DECL_ASSEMBLER_NAME_SET_P (decl)) - SET_DECL_RTL (decl, NULL); + /* Replace non-alphanumeric characters with underscores as the suffix. + */ + std::string suffix = ""; + for (const char *c = version_string; *c; c++) + suffix += ISALNUM (*c) == 0 ? '_' : *c; - id = get_identifier (name.c_str ()); + id = clone_identifier (id, suffix.c_str ()); + } } - return id; } @@ -14434,22 +14433,6 @@ dispatch_function_versions (tree dispatch_decl, return 0; } -/* Return an identifier for the base assembler name of a versioned function. - This is computed by taking the default version's assembler name, and - stripping off the ".default" suffix if it's already been appended. */ - -static tree -get_suffixed_assembler_name (tree default_decl, const char *suffix) -{ - std::string name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (default_decl)); - - auto size = name.size (); - if (size >= 8 && name.compare (size - 8, 8, ".default") == 0) - name.resize (size - 8); - name += suffix; - return get_identifier (name.c_str ()); -} - /* Make the resolver function decl to dispatch the versions of a multi-versioned function, DEFAULT_DECL. IFUNC_ALIAS_DECL is ifunc alias that will point to the created resolver. Create an @@ -14463,10 +14446,8 @@ make_resolver_func (const tree default_decl, { tree decl, type, t; - /* Create resolver function name based on default_decl. We need to remove an - existing ".default" suffix if this has already been appended. */ - tree decl_name = get_suffixed_assembler_name (default_decl, ".resolver"); - const char *resolver_name = IDENTIFIER_POINTER (decl_name); + cgraph_node *node = cgraph_node::get (default_decl); + gcc_assert (node && node->function_version ()); /* The resolver function should have signature (void *) resolver (uint64_t, void *) */ @@ -14475,10 +14456,21 @@ make_resolver_func (const tree default_decl, ptr_type_node, NULL_TREE); - decl = build_fn_decl (resolver_name, type); - SET_DECL_ASSEMBLER_NAME (decl, decl_name); + decl = build_fn_decl (IDENTIFIER_POINTER (DECL_NAME (default_decl)), type); + + /* Set the assembler name to prevent cgraph_node attempting to mangle. */ + SET_DECL_ASSEMBLER_NAME (decl, DECL_ASSEMBLER_NAME (default_decl)); + + cgraph_node *resolver_node = cgraph_node::get_create (decl); + resolver_node->dispatcher_resolver_function = true; + + if (node->is_target_clone) + resolver_node->is_target_clone = true; + + tree id = riscv_mangle_decl_assembler_name + (decl, node->function_version ()->assembler_name); + symtab->change_decl_assembler_name (decl, id); - DECL_NAME (decl) = decl_name; TREE_USED (decl) = 1; DECL_ARTIFICIAL (decl) = 1; DECL_IGNORED_P (decl) = 1; @@ -14543,7 +14535,7 @@ make_resolver_func (const tree default_decl, gcc_assert (ifunc_alias_decl != NULL); /* Mark ifunc_alias_decl as "ifunc" with resolver as resolver_name. */ DECL_ATTRIBUTES (ifunc_alias_decl) - = make_attribute ("ifunc", resolver_name, + = make_attribute ("ifunc", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), DECL_ATTRIBUTES (ifunc_alias_decl)); /* Create the alias for dispatch to resolver here. */ @@ -14608,27 +14600,6 @@ riscv_generate_version_dispatcher_body (void *node_p) cgraph_edge::rebuild_edges (); pop_cfun (); - /* Fix up symbol names. First we need to obtain the base name, which may - have already been mangled. */ - tree base_name = get_suffixed_assembler_name (default_ver_decl, ""); - - /* We need to redo the version mangling on the non-default versions for the - target_clones case. Redoing the mangling for the target_version case is - redundant but does no harm. We need to skip the default version, because - expand_clones will append ".default" later; fortunately that suffix is the - one we want anyway. */ - for (versn_info = node_version_info->next->next; versn_info; - versn_info = versn_info->next) - { - tree version_decl = versn_info->this_node->decl; - tree name = riscv_mangle_decl_assembler_name (version_decl, - base_name); - symtab->change_decl_assembler_name (version_decl, name); - } - - /* We also need to use the base name for the ifunc declaration. */ - symtab->change_decl_assembler_name (node->decl, base_name); - return resolver_decl; } @@ -14672,20 +14643,9 @@ riscv_get_function_versions_dispatcher (void *decl) if (targetm.has_ifunc_p ()) { struct cgraph_function_version_info *it_v = NULL; - struct cgraph_node *dispatcher_node = NULL; - struct cgraph_function_version_info *dispatcher_version_info = NULL; /* Right now, the dispatching is done via ifunc. */ dispatch_decl = make_dispatcher_decl (default_node->decl); - TREE_NOTHROW (dispatch_decl) = TREE_NOTHROW (fn); - - dispatcher_node = cgraph_node::get_create (dispatch_decl); - gcc_assert (dispatcher_node != NULL); - dispatcher_node->dispatcher_function = 1; - dispatcher_version_info - = dispatcher_node->insert_new_function_version (); - dispatcher_version_info->next = default_version_info; - dispatcher_node->definition = 1; /* Set the dispatcher for all the versions. */ it_v = default_version_info; diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 8dd23f8619c..d00d5f27121 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -87,6 +87,7 @@ extern tree rs6000_builtin_mask_for_load (void); extern tree rs6000_builtin_md_vectorized_function (tree, tree, tree); extern tree rs6000_builtin_reciprocal (tree); +static tree rs6000_mangle_decl_assembler_name (tree, tree); /* Set -mabi=ieeelongdouble on some old targets. In the future, power server systems will also set long double to be IEEE 128-bit. AIX and Darwin @@ -25366,20 +25367,9 @@ rs6000_get_function_versions_dispatcher (void *decl) if (targetm.has_ifunc_p ()) { struct cgraph_function_version_info *it_v = NULL; - struct cgraph_node *dispatcher_node = NULL; - struct cgraph_function_version_info *dispatcher_version_info = NULL; /* Right now, the dispatching is done via ifunc. */ dispatch_decl = make_dispatcher_decl (default_node->decl); - TREE_NOTHROW (dispatch_decl) = TREE_NOTHROW (fn); - - dispatcher_node = cgraph_node::get_create (dispatch_decl); - gcc_assert (dispatcher_node != NULL); - dispatcher_node->dispatcher_function = 1; - dispatcher_version_info - = dispatcher_node->insert_new_function_version (); - dispatcher_version_info->next = default_version_info; - dispatcher_node->definition = 1; /* Set the dispatcher for all the versions. */ it_v = default_version_info; @@ -25412,13 +25402,24 @@ make_resolver_func (const tree default_decl, { /* Make the resolver function static. The resolver function returns void *. */ - tree decl_name = clone_function_name (default_decl, "resolver"); - const char *resolver_name = IDENTIFIER_POINTER (decl_name); tree type = build_function_type_list (ptr_type_node, NULL_TREE); - tree decl = build_fn_decl (resolver_name, type); - SET_DECL_ASSEMBLER_NAME (decl, decl_name); + tree decl = build_fn_decl (IDENTIFIER_POINTER (DECL_NAME (default_decl)), + type); + + cgraph_node *node = cgraph_node::get (default_decl); + gcc_assert (node && node->function_version ()); + + /* Set the assembler name to prevent cgraph_node attempting to mangle. */ + SET_DECL_ASSEMBLER_NAME (decl, DECL_ASSEMBLER_NAME (default_decl)); - DECL_NAME (decl) = decl_name; + cgraph_node *resolver_node = cgraph_node::get_create (decl); + resolver_node->dispatcher_resolver_function = true; + + tree id = rs6000_mangle_decl_assembler_name + (decl, node->function_version ()->assembler_name); + symtab->change_decl_assembler_name (decl, id); + + DECL_NAME (decl) = DECL_NAME (default_decl); TREE_USED (decl) = 1; DECL_ARTIFICIAL (decl) = 1; DECL_IGNORED_P (decl) = 0; @@ -25464,7 +25465,8 @@ make_resolver_func (const tree default_decl, /* Mark dispatch_decl as "ifunc" with resolver as resolver_name. */ DECL_ATTRIBUTES (dispatch_decl) - = make_attribute ("ifunc", resolver_name, DECL_ATTRIBUTES (dispatch_decl)); + = make_attribute ("ifunc", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), + DECL_ATTRIBUTES (dispatch_decl)); cgraph_node::create_same_body_alias (dispatch_decl, decl); @@ -28507,6 +28509,44 @@ complex_divide_builtin_code (machine_mode mode) return (built_in_function) func; } +/* This function changes the assembler name for functions that are + versions. If DECL is a function version and has a "target" + attribute, it appends the attribute string to its assembler name. */ + +static tree +rs6000_mangle_function_version_assembler_name (tree decl, tree id) +{ + tree version_attr; + const char *version_string; + char *attr_str; + + if (DECL_DECLARED_INLINE_P (decl) + && lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (decl))) + error_at (DECL_SOURCE_LOCATION (decl), + "function versions cannot be marked as %," + " bodies have to be generated"); + + if (DECL_VIRTUAL_P (decl) || DECL_VINDEX (decl)) + sorry ("virtual function multiversioning not supported"); + + version_attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl)); + + /* target attribute string cannot be NULL. */ + gcc_assert (version_attr != NULL_TREE); + + version_string = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (version_attr))); + + if (strcmp (version_string, "default") == 0) + return clone_identifier (id, "default"); + + attr_str = sorted_attr_string (TREE_VALUE (version_attr)); + + tree ret = clone_identifier (id, attr_str, true); + + XDELETEVEC (attr_str); + return ret; +} + /* On 64-bit Linux and Freebsd systems, possibly switch the long double library function names from l to f128 if the default long double type is IEEE 128-bit. Typically, with the C and C++ languages, the standard math.h @@ -28692,6 +28732,14 @@ rs6000_mangle_decl_assembler_name (tree decl, tree id) } } + if (TREE_CODE (decl) == FUNCTION_DECL) + { + cgraph_node *node = cgraph_node::get (decl); + if (node && node->dispatcher_resolver_function) + id = clone_identifier (id, "resolver"); + else if (DECL_FUNCTION_VERSIONED (decl)) + id = rs6000_mangle_function_version_assembler_name (decl, id); + } return id; } diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index a6a98426ed9..8f21ea837b1 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -1273,6 +1273,13 @@ maybe_mark_function_versioned (tree decl) { if (!DECL_FUNCTION_VERSIONED (decl)) { + /* We need to insert function version now to make sure the correct + pre-mangled assembler name is recorded. */ + cgraph_node *node = cgraph_node::get_create (decl); + + if (!node->function_version ()) + node->insert_new_function_version (); + DECL_FUNCTION_VERSIONED (decl) = 1; /* If DECL_ASSEMBLER_NAME has already been set, re-mangle to include the version marker. */ diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc index d25277c0a93..dc3b72c8e85 100644 --- a/gcc/multiple_target.cc +++ b/gcc/multiple_target.cc @@ -166,9 +166,6 @@ create_dispatcher_calls (struct cgraph_node *node) } } - tree fname = clone_function_name (node->decl, "default"); - symtab->change_decl_assembler_name (node->decl, fname); - if (node->definition) { /* FIXME: copy of cgraph_node::make_local that should be cleaned up @@ -184,100 +181,6 @@ create_dispatcher_calls (struct cgraph_node *node) } } -/* Create string with attributes separated by TARGET_CLONES_ATTR_SEPARATOR. - Return number of attributes. */ - -static int -get_attr_str (tree arglist, char *attr_str) -{ - tree arg; - size_t str_len_sum = 0; - int argnum = 0; - - for (arg = arglist; arg; arg = TREE_CHAIN (arg)) - { - const char *str = TREE_STRING_POINTER (TREE_VALUE (arg)); - size_t len = strlen (str); - for (const char *p = strchr (str, TARGET_CLONES_ATTR_SEPARATOR); - p; - p = strchr (p + 1, TARGET_CLONES_ATTR_SEPARATOR)) - argnum++; - memcpy (attr_str + str_len_sum, str, len); - attr_str[str_len_sum + len] - = TREE_CHAIN (arg) ? TARGET_CLONES_ATTR_SEPARATOR : '\0'; - str_len_sum += len + 1; - argnum++; - } - return argnum; -} - -/* Return number of attributes separated by TARGET_CLONES_ATTR_SEPARATOR - and put them into ARGS. - If there is no DEFAULT attribute return -1. - If there is an empty string in attribute return -2. - If there are multiple DEFAULT attributes return -3. - */ - -static int -separate_attrs (char *attr_str, char **attrs, int attrnum) -{ - int i = 0; - int default_count = 0; - static const char separator_str[] = { TARGET_CLONES_ATTR_SEPARATOR, 0 }; - - for (char *attr = strtok (attr_str, separator_str); - attr != NULL; attr = strtok (NULL, separator_str)) - { - if (strcmp (attr, "default") == 0) - { - default_count++; - continue; - } - attrs[i++] = attr; - } - if (default_count == 0) - return -1; - else if (default_count > 1) - return -3; - else if (i + default_count < attrnum) - return -2; - - return i; -} - -/* Return true if symbol is valid in assembler name. */ - -static bool -is_valid_asm_symbol (char c) -{ - if ('a' <= c && c <= 'z') - return true; - if ('A' <= c && c <= 'Z') - return true; - if ('0' <= c && c <= '9') - return true; - if (c == '_') - return true; - return false; -} - -/* Replace all not valid assembler symbols with '_'. */ - -static void -create_new_asm_name (char *old_asm_name, char *new_asm_name) -{ - int i; - int old_name_len = strlen (old_asm_name); - - /* Replace all not valid assembler symbols with '_'. */ - for (i = 0; i < old_name_len; i++) - if (!is_valid_asm_symbol (old_asm_name[i])) - new_asm_name[i] = '_'; - else - new_asm_name[i] = old_asm_name[i]; - new_asm_name[old_name_len] = '\0'; -} - /* Creates target clone of NODE. */ static cgraph_node * @@ -313,7 +216,6 @@ create_target_clone (cgraph_node *node, bool definition, char *name, static bool expand_target_clones (struct cgraph_node *node, bool definition) { - int i; /* Parsing target attributes separated by TARGET_CLONES_ATTR_SEPARATOR. */ tree attr_target = lookup_attribute ("target_clones", DECL_ATTRIBUTES (node->decl)); @@ -321,11 +223,12 @@ expand_target_clones (struct cgraph_node *node, bool definition) if (!attr_target) return false; - tree arglist = TREE_VALUE (attr_target); - int attr_len = get_target_clone_attr_len (arglist); + int num_defaults = 0; + auto_vec attr_list = get_clone_versions (node->decl, + &num_defaults); /* No need to clone for 1 target attribute. */ - if (attr_len == -1) + if (attr_list.length () == 1) { warning_at (DECL_SOURCE_LOCATION (node->decl), 0, "single % attribute is ignored"); @@ -352,95 +255,96 @@ expand_target_clones (struct cgraph_node *node, bool definition) return false; } - char *attr_str = XNEWVEC (char, attr_len); - int attrnum = get_attr_str (arglist, attr_str); - char **attrs = XNEWVEC (char *, attrnum); - - attrnum = separate_attrs (attr_str, attrs, attrnum); - switch (attrnum) + /* Disallow multiple defaults. */ + if (num_defaults > 1) { - case -1: - error_at (DECL_SOURCE_LOCATION (node->decl), - "% target was not set"); - break; - case -2: - error_at (DECL_SOURCE_LOCATION (node->decl), - "an empty string cannot be in % attribute"); - break; - case -3: error_at (DECL_SOURCE_LOCATION (node->decl), "multiple % targets were set"); - break; - default: - break; + return false; } - - if (attrnum < 0) + /* Disallow target clones with no defaults. */ + if (num_defaults == 0) { - XDELETEVEC (attrs); - XDELETEVEC (attr_str); + error_at (DECL_SOURCE_LOCATION (node->decl), + "% target was not set"); return false; } - const char *new_attr_name = (TARGET_HAS_FMV_TARGET_ATTRIBUTE - ? "target" : "target_version"); - cgraph_function_version_info *decl1_v = NULL; - cgraph_function_version_info *decl2_v = NULL; - cgraph_function_version_info *before = NULL; - cgraph_function_version_info *after = NULL; - decl1_v = node->function_version (); - if (decl1_v == NULL) - decl1_v = node->insert_new_function_version (); - before = decl1_v; - DECL_FUNCTION_VERSIONED (node->decl) = 1; - - for (i = 0; i < attrnum; i++) + /* Disallow any empty values in the clone attr. */ + for (string_slice attr : attr_list) + if (attr.empty () || !attr.is_valid ()) + { + error_at (DECL_SOURCE_LOCATION (node->decl), + "an empty string cannot be in % attribute"); + return false; + } + + string_slice new_attr_name = TARGET_HAS_FMV_TARGET_ATTRIBUTE + ? "target" + : "target_version"; + + cgraph_function_version_info *node_v = node->function_version (); + + if (!node_v) + node_v = node->insert_new_function_version (); + + /* If this target_clones contains a default, then convert this node to the + default. If this node does not contain default (this is only possible + in target_version semantics) then remove the node. This is safe at this + point as only target_clones declarations containing default version is + resolvable so this decl will have no calls/references. */ + + tree attrs = remove_attribute ("target_clones", + DECL_ATTRIBUTES (node->decl)); + tree assembler_name = node_v->assembler_name; + + /* Change the current node into the default node. */ + gcc_assert (num_defaults == 1); + + /* Setting new attribute to initial function. */ + tree attributes = make_attribute (new_attr_name, "default", attrs); + DECL_ATTRIBUTES (node->decl) = attributes; + DECL_FUNCTION_VERSIONED (node->decl) = true; + + node->is_target_clone = true; + node->local = false; + + /* Remangle base node after new target version string set. */ + tree id = targetm.mangle_decl_assembler_name (node->decl, assembler_name); + symtab->change_decl_assembler_name (node->decl, id); + + for (string_slice attr : attr_list) { - char *attr = attrs[i]; + /* Skip default nodes. */ + if (attr == "default") + continue; /* Create new target clone. */ - tree attributes = make_attribute (new_attr_name, attr, - DECL_ATTRIBUTES (node->decl)); - - char *suffix = XNEWVEC (char, strlen (attr) + 1); - create_new_asm_name (attr, suffix); - cgraph_node *new_node = create_target_clone (node, definition, suffix, - attributes); - XDELETEVEC (suffix); + tree attributes = make_attribute (new_attr_name, attr, attrs); + + cgraph_node *new_node + = create_target_clone (node, definition, NULL, attributes); if (new_node == NULL) - { - XDELETEVEC (attrs); - XDELETEVEC (attr_str); - return false; - } + return false; new_node->local = false; - decl2_v = new_node->function_version (); - if (decl2_v != NULL) - continue; - decl2_v = new_node->insert_new_function_version (); - - /* Chain decl2_v and decl1_v. All semantically identical versions - will be chained together. */ - after = decl2_v; - while (before->next != NULL) - before = before->next; - while (after->prev != NULL) - after = after->prev; - - before->next = after; - after->prev = before; - DECL_FUNCTION_VERSIONED (new_node->decl) = 1; + DECL_FUNCTION_VERSIONED (new_node->decl) = true; + if (!node_v) + node_v = new_node->insert_new_function_version (); + else + cgraph_node::add_function_version (node_v, new_node->decl); + + /* Use the base node's assembler name for all created nodes. */ + new_node->function_version ()->assembler_name = assembler_name; + new_node->is_target_clone = true; + + /* Mangle all new nodes. */ + tree id = targetm.mangle_decl_assembler_name + (new_node->decl, new_node->function_version ()->assembler_name); + symtab->change_decl_assembler_name (new_node->decl, id); } - XDELETEVEC (attrs); - XDELETEVEC (attr_str); - /* Setting new attribute to initial function. */ - tree attributes = make_attribute (new_attr_name, "default", - DECL_ATTRIBUTES (node->decl)); - DECL_ATTRIBUTES (node->decl) = attributes; - node->local = false; return true; } diff --git a/gcc/testsuite/g++.target/i386/mv-symbols1.C b/gcc/testsuite/g++.target/i386/mv-symbols1.C index 1290299aea5..3163f03ddd8 100644 --- a/gcc/testsuite/g++.target/i386/mv-symbols1.C +++ b/gcc/testsuite/g++.target/i386/mv-symbols1.C @@ -55,14 +55,14 @@ int bar(int x) /* { dg-final { scan-assembler-times "\n_Z3foov\.arch_slm:\n" 1 } } */ /* { dg-final { scan-assembler-times "\n_Z3foov\.sse4.2:\n" 1 } } */ /* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */ -/* { dg-final { scan-assembler-times "\n\tcall\t_Z7_Z3foovv\n" 1 } } */ -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z7_Z3foovv, @gnu_indirect_function\n" 1 } } */ -/* { dg-final { scan-assembler-times "\n\t\.set\t_Z7_Z3foovv,_Z3foov\.resolver\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tcall\t_Z3foov.ifunc\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov.ifunc, @gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\t_Z3foov.ifunc,_Z3foov\.resolver\n" 1 } } */ /* { dg-final { scan-assembler-times "\n_Z3fooi:\n" 1 } } */ /* { dg-final { scan-assembler-times "\n_Z3fooi\.arch_slm:\n" 1 } } */ /* { dg-final { scan-assembler-times "\n_Z3fooi\.sse4.2:\n" 1 } } */ /* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 1 } } */ -/* { dg-final { scan-assembler-times "\n\tcall\t_Z7_Z3fooii\n" 1 } } */ -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z7_Z3fooii, @gnu_indirect_function\n" 1 } } */ -/* { dg-final { scan-assembler-times "\n\t\.set\t_Z7_Z3fooii,_Z3fooi\.resolver\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tcall\t_Z3fooi.ifunc\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi.ifunc, @gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\t_Z3fooi.ifunc,_Z3fooi\.resolver\n" 1 } } */ diff --git a/gcc/testsuite/g++.target/i386/mv-symbols3.C b/gcc/testsuite/g++.target/i386/mv-symbols3.C index a5cf3445a43..67b27351143 100644 --- a/gcc/testsuite/g++.target/i386/mv-symbols3.C +++ b/gcc/testsuite/g++.target/i386/mv-symbols3.C @@ -32,13 +32,13 @@ int bar() /* { dg-final { scan-assembler-times "\n_Z3foov\.arch_slm:\n" 0 } } */ /* { dg-final { scan-assembler-times "\n_Z3foov\.sse4.2:\n" 0 } } */ /* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */ -/* { dg-final { scan-assembler-times "\n\tcall\t_Z7_Z3foovv\n" 1 } } */ -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z7_Z3foovv, @gnu_indirect_function\n" 1 } } */ -/* { dg-final { scan-assembler-times "\n\t\.set\t_Z7_Z3foovv,_Z3foov\.resolver\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tcall\t_Z3foov.ifunc\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov.ifunc, @gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\t_Z3foov.ifunc,_Z3foov\.resolver\n" 1 } } */ /* { dg-final { scan-assembler-times "\n_Z3fooi:\n" 0 } } */ /* { dg-final { scan-assembler-times "\n_Z3fooi\.arch_slm:\n" 0 } } */ /* { dg-final { scan-assembler-times "\n_Z3fooi\.sse4.2:\n" 0 } } */ /* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 0 } } */ -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z7_Z3fooii, @gnu_indirect_function\n" 0 } } */ -/* { dg-final { scan-assembler-times "\n\t\.set\t_Z7_Z3fooii,_Z3fooi\.resolver\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi.ifunc, @gnu_indirect_function\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\t_Z3fooi.ifunc,_Z3fooi\.resolver\n" 0 } } */ diff --git a/gcc/testsuite/g++.target/i386/mv-symbols4.C b/gcc/testsuite/g++.target/i386/mv-symbols4.C index bb10f126f67..c82db70da35 100644 --- a/gcc/testsuite/g++.target/i386/mv-symbols4.C +++ b/gcc/testsuite/g++.target/i386/mv-symbols4.C @@ -38,13 +38,13 @@ int bar() /* { dg-final { scan-assembler-times "\n_Z3foov\.arch_slm:\n" 0 } } */ /* { dg-final { scan-assembler-times "\n_Z3foov\.sse4.2:\n" 0 } } */ /* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */ -/* { dg-final { scan-assembler-times "\n\tcall\t_Z7_Z3foovv\n" 1 } } */ -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z7_Z3foovv, @gnu_indirect_function\n" 1 } } */ -/* { dg-final { scan-assembler-times "\n\t\.set\t_Z7_Z3foovv,_Z3foov\.resolver\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tcall\t_Z3foov.ifunc\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov.ifunc, @gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\t_Z3foov.ifunc,_Z3foov\.resolver\n" 1 } } */ /* { dg-final { scan-assembler-times "\n_Z3fooi:\n" 1 } } */ /* { dg-final { scan-assembler-times "\n_Z3fooi\.arch_slm:\n" 0 } } */ /* { dg-final { scan-assembler-times "\n_Z3fooi\.sse4.2:\n" 0 } } */ /* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 0 } } */ -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z7_Z3fooii, @gnu_indirect_function\n" 0 } } */ -/* { dg-final { scan-assembler-times "\n\t\.set\t_Z7_Z3fooii,_Z3fooi\.resolver\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi.ifunc, @gnu_indirect_function\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\t_Z3fooi.ifunc,_Z3fooi\.resolver\n" 0 } } */ diff --git a/gcc/testsuite/g++.target/i386/mv-symbols5.C b/gcc/testsuite/g++.target/i386/mv-symbols5.C index d36e4c304c2..7792f113f22 100644 --- a/gcc/testsuite/g++.target/i386/mv-symbols5.C +++ b/gcc/testsuite/g++.target/i386/mv-symbols5.C @@ -44,13 +44,13 @@ int bar() /* { dg-final { scan-assembler-times "\n_Z3foov\.arch_slm:\n" 1 } } */ /* { dg-final { scan-assembler-times "\n_Z3foov\.sse4.2:\n" 1 } } */ /* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */ -/* { dg-final { scan-assembler-times "\n\tcall\t_Z7_Z3foovv\n" 1 } } */ -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z7_Z3foovv, @gnu_indirect_function\n" 1 } } */ -/* { dg-final { scan-assembler-times "\n\t\.set\t_Z7_Z3foovv,_Z3foov\.resolver\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tcall\t_Z3foov.ifunc\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov.ifunc, @gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\t_Z3foov.ifunc,_Z3foov\.resolver\n" 1 } } */ /* { dg-final { scan-assembler-times "\n_Z3fooi:\n" 0 } } */ /* { dg-final { scan-assembler-times "\n_Z3fooi\.arch_slm:\n" 1 } } */ /* { dg-final { scan-assembler-times "\n_Z3fooi\.sse4.2:\n" 1 } } */ /* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 0 } } */ -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z7_Z3fooii, @gnu_indirect_function\n" 0 } } */ -/* { dg-final { scan-assembler-times "\n\t\.set\t_Z7_Z3fooii,_Z3fooi\.resolver\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi.ifunc, @gnu_indirect_function\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\t_Z3fooi.ifunc,_Z3fooi\.resolver\n" 0 } } */ diff --git a/gcc/tree.cc b/gcc/tree.cc index 5d52a3886ce..56b2b86d8bb 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -15424,32 +15424,6 @@ get_attr_nonstring_decl (tree expr, tree *ref) return NULL_TREE; } -/* Return length of attribute names string, - if arglist chain > 1, -1 otherwise. */ - -int -get_target_clone_attr_len (tree arglist) -{ - tree arg; - int str_len_sum = 0; - int argnum = 0; - - for (arg = arglist; arg; arg = TREE_CHAIN (arg)) - { - const char *str = TREE_STRING_POINTER (TREE_VALUE (arg)); - size_t len = strlen (str); - str_len_sum += len + 1; - for (const char *p = strchr (str, TARGET_CLONES_ATTR_SEPARATOR); - p; - p = strchr (p + 1, TARGET_CLONES_ATTR_SEPARATOR)) - argnum++; - argnum++; - } - if (argnum <= 1) - return -1; - return str_len_sum; -} - /* Returns an auto_vec of string_slices containing the version strings from ARGLIST. DEFAULT_COUNT is incremented for each default version found. */ diff --git a/gcc/tree.h b/gcc/tree.h index ce8c778087f..6d28f2dddd8 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -7101,8 +7101,6 @@ extern unsigned fndecl_dealloc_argno (tree); object or pointer. Otherwise return null. */ extern tree get_attr_nonstring_decl (tree, tree * = NULL); -extern int get_target_clone_attr_len (tree); - /* Returns the version string for a decl with target_version attribute. Returns an invalid string_slice if no attribute is present. */ extern string_slice get_target_version (const tree); From patchwork Wed Sep 17 12:44:54 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alfie Richards X-Patchwork-Id: 120426 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6C74D385843A for ; Wed, 17 Sep 2025 12:53:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6C74D385843A Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=selector1 header.b=Etp9G36A; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=selector1 header.b=Etp9G36A X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from AM0PR83CU005.outbound.protection.outlook.com (mail-westeuropeazon11010031.outbound.protection.outlook.com [52.101.69.31]) by sourceware.org (Postfix) with ESMTPS id EEB50385828B for ; Wed, 17 Sep 2025 12:46:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org EEB50385828B Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org EEB50385828B Authentication-Results: server2.sourceware.org; arc=pass smtp.remote-ip=52.101.69.31 ARC-Seal: i=3; a=rsa-sha256; d=sourceware.org; s=key; t=1758113190; cv=pass; b=iTddJzjF3hlQD1x3jHVRKN1ae1UL3IUbx1NySkp1/6bkrH/OZ85jd+ywDtGiKVO14blEGYr3HpbhnApaLWn9U8/a9WUsdRYUZvElHyp54pQnq4yeC4xZrJ+4fKtJ2elfQUSBdrOW7Zp7Db7g4VEZMBxLZIP2AQo2eJauMHkPCtY= ARC-Message-Signature: i=3; a=rsa-sha256; d=sourceware.org; s=key; t=1758113190; c=relaxed/simple; bh=aAb197kdGP9027YrkoIgbturRKdV3Ox2Y3N+t0lXUqs=; h=DKIM-Signature:DKIM-Signature:From:To:Subject:Date:Message-ID: MIME-Version; b=WGosx4CMwoq3tptrKs59iyeKOLen5NA9nryDOmiVJRkED5m08sDy1gnXQoypvSxhr2QdRIbFIwpEjlg6F5+1u1GZH0wnFOoDd7Le6nUnsJbeY5N/Gbw485mW37PG6W5DYLeFx4vxM8B+fmtg3COPAsA6x9UUWY+5opvTLR5j0Zs= ARC-Authentication-Results: i=3; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EEB50385828B ARC-Seal: i=2; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=pass; b=csV+oBulJf9SjVs+QY+OensCog/4m/sLcb2q85DoLduX7+yALB2YTStsNeC72zuM7PqUiQ5YfDdGNli5/SDMp+D8CjolYCHlU5BluOx4XlxTteKW4QY5Fzmm32jghiAq8AbHwva8+IuRy03ig5TTSCnzA9rSLgsNgFL+RhbOGV/euVKwTbOVAcl3DgLO22lgVfjnoOm46HDAeaOcmML+kA56uHZ/6Gevc9wje2rBgMHMwRX89wW/YsDVAMnfxQ6XVGm7MJzHWE+B/P2n6CCQTG58q4823eu0nV8GzFgUtaG/KigxiXCY0BZh+LWz0Z55N650+6a2t+dusaDj90YC7A== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=of3pNfnX3nBpynZVkDvqEgIXCBdaOlepXo2cBB0YIf0=; b=nVFQ30Y2ec0+KHk9+Pe+MJYXK+bpHM6rtDxDLtuijAtNCHZDFabBnwmFvpDs4fm0qJl1cByCwUTlxdLYQKrFqZTfSCExYJB95mYVutfVn7og68vwX+5krjQTRt5OrJZffqB/fDwBp66FDtp9q0DeCg9fp/2KjKapLzNG1T0I5H5UbvQ1xtY6mlyP6jEl0KK+PYk4u4w69YMhxeU9baAMUC6AIRFANlcw+ox49+JwkTa44cUh1LjikEicbnRDLgi+3P/MOwbPr69CVyPpWrAmmWgr5MLHxxHOzQvEhfxWYPOIOTsrqBholB6zMiDXRq+dIwH0a4ROnZpzYeQV5huayw== ARC-Authentication-Results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 4.158.2.129) smtp.rcpttodomain=gcc.gnu.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=pass (signature was verified) header.d=arm.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dmarc=[1,1,header.from=arm.com]) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=arm.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=of3pNfnX3nBpynZVkDvqEgIXCBdaOlepXo2cBB0YIf0=; b=Etp9G36ASsGOelZAS8TSb7Ih3K6i9qGtv9f/O7/mXYZS9yFenbFDd8pPmryc7EiE4a7XawgzDQpy7dkE6YlxCKMOmOR2LYtoDrbt2lFYZfawKMGVJFmwbwXgh7eEzfDW0elxue2oA71cTYIf1PzWZdP64gm8UgUgtsec9q9c8vs= Received: from AM7PR02CA0017.eurprd02.prod.outlook.com (2603:10a6:20b:100::27) by GV2PR08MB7956.eurprd08.prod.outlook.com (2603:10a6:150:a9::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9115.19; Wed, 17 Sep 2025 12:46:21 +0000 Received: from AM3PEPF0000A79B.eurprd04.prod.outlook.com (2603:10a6:20b:100:cafe::fe) by AM7PR02CA0017.outlook.office365.com (2603:10a6:20b:100::27) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.13 via Frontend Transport; Wed, 17 Sep 2025 12:46:21 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 4.158.2.129) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=arm.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 4.158.2.129 as permitted sender) receiver=protection.outlook.com; client-ip=4.158.2.129; helo=outbound-uk1.az.dlp.m.darktrace.com; pr=C Received: from outbound-uk1.az.dlp.m.darktrace.com (4.158.2.129) by AM3PEPF0000A79B.mail.protection.outlook.com (10.167.16.106) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Wed, 17 Sep 2025 12:46:20 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=JPiOVz6EsoXoUAHGnfQRCewhsLz2GwQevarIFpM2EUCWviy/xBxb8KAIn8aME67gdXTeULWFoSkNUTUNYNBsWWyHszgW35xlZ0WrQNsHCHqcDwRNbtOSPJeDEQyIPCRRLX+goGS2KccqN7You1vhJSvYJdgecklyv24Bkv4bOxwVmbZpqlZ9njIVUj9NS7XEn76as9R1xyNxQpdTJrzKhyHcm6EGfk7m2+GH4XY64GYBsbO6XGztqAymovpjQ278tTHTYudK55nahBrw+YzmGMaZxQ70ZPN8+e8W84CgVTZolaF+nf+kd2GINUep4bJjkP7ompYYXE5q2IUQqH1UbQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=of3pNfnX3nBpynZVkDvqEgIXCBdaOlepXo2cBB0YIf0=; b=BulrVoZErRRL5u6JO61fNTTeYOJSvswkJmcNOE2fEqh6dLVK+I7KBE0124M4iKgUSDp8PpWjiPDy2vRC0FyzxQLjK6070Na3AMSP0dJJw41ETxeURDruKzVOgootgJTCtb0VmjPo+acHdZdhfghPE4VcRXbRueGlfhaBnOi+3AOiQvuDwS7dpiQVWlm4Zz5xGYKy2PpXCBfeSRg9U8QZGj0rt/9zQPf1tubEDwV2QwotjdHGAkYwfMpEQOvZOHgi7/fhm/Gkx/Zfl6ZJ06rkVsjXpmaJnKEuMhZmt9wJ7HaOxa/Tt2bPt+PP1tg6c23Jew0fRnRQ+jcP/eij2ntolA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 172.205.89.229) smtp.rcpttodomain=gcc.gnu.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=arm.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=of3pNfnX3nBpynZVkDvqEgIXCBdaOlepXo2cBB0YIf0=; b=Etp9G36ASsGOelZAS8TSb7Ih3K6i9qGtv9f/O7/mXYZS9yFenbFDd8pPmryc7EiE4a7XawgzDQpy7dkE6YlxCKMOmOR2LYtoDrbt2lFYZfawKMGVJFmwbwXgh7eEzfDW0elxue2oA71cTYIf1PzWZdP64gm8UgUgtsec9q9c8vs= Received: from AM4PR07CA0029.eurprd07.prod.outlook.com (2603:10a6:205:1::42) by VI1PR08MB10199.eurprd08.prod.outlook.com (2603:10a6:800:1bf::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.13; Wed, 17 Sep 2025 12:45:43 +0000 Received: from AM3PEPF0000A796.eurprd04.prod.outlook.com (2603:10a6:205:1:cafe::da) by AM4PR07CA0029.outlook.office365.com (2603:10a6:205:1::42) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.13 via Frontend Transport; Wed, 17 Sep 2025 12:45:43 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 172.205.89.229) smtp.mailfrom=arm.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 172.205.89.229 as permitted sender) receiver=protection.outlook.com; client-ip=172.205.89.229; helo=nebula.arm.com; pr=C Received: from nebula.arm.com (172.205.89.229) by AM3PEPF0000A796.mail.protection.outlook.com (10.167.16.101) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.9137.12 via Frontend Transport; Wed, 17 Sep 2025 12:45:43 +0000 Received: from AZ-NEU-EX04.Arm.com (10.240.25.138) by AZ-NEU-EX06.Arm.com (10.240.25.134) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Wed, 17 Sep 2025 12:44:58 +0000 Received: from AZ-NEU-EX05.Arm.com (10.240.25.133) by AZ-NEU-EX04.Arm.com (10.240.25.138) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.2562.27; Wed, 17 Sep 2025 12:44:58 +0000 Received: from ip-10-248-139-135.eu-west-1.compute.internal (10.248.139.135) by mail.arm.com (10.240.25.133) with Microsoft SMTP Server id 15.1.2507.39 via Frontend Transport; Wed, 17 Sep 2025 12:44:58 +0000 From: To: , CC: , , , , , , , , , , , , , Alfie Richards Subject: [PATCH v11 07/13] c++: Refactor FMV frontend conflict and merging logic and hooks. Date: Wed, 17 Sep 2025 12:44:54 +0000 Message-ID: <20250917124456.170437-3-alfie.richards@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250917124456.170437-1-alfie.richards@arm.com> References: <20250917124456.170437-1-alfie.richards@arm.com> MIME-Version: 1.0 X-EOPAttributedMessage: 1 X-MS-TrafficTypeDiagnostic: AM3PEPF0000A796:EE_|VI1PR08MB10199:EE_|AM3PEPF0000A79B:EE_|GV2PR08MB7956:EE_ X-MS-Office365-Filtering-Correlation-Id: a3f93a14-1dc2-49b2-2302-08ddf5e833e3 x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; ARA:13230040|36860700013|82310400026|7416014|376014|1800799024|3122999003; X-Microsoft-Antispam-Message-Info-Original: 10OjPIn7ZNy4aawpaIuvBezUVbYIgFZLA8hXWdKmLIl4sqI+5rFlOGDW4seh3zRbzw2eXsb/Ed0CqKqrqbFdi7lUlKOB5P8hSHVPbhyfpfJ8P+3AN3wUUp6Ti94TXA/d/vJSGjU6LPRpMTnQzyEXPW5WPfYVhTTvep7pNCfXdnPJ+D0EtRObzHGjycKrGywRiOvcPSt32JPoU05k6dY4vO2MoZDJn7aFzNSjoz3Od7aRBKPZLhIwqv3M2FIEINypT93UjFwKxmzupSTgR/WZ4brmLBCte0Zdvhjp9fpFmmDlv42G4QYzO6peRtMtm5OBdMTYqYEGCrQhp9i6Oek99ZBKa7jqKG+2fmdqWHo3+/n/FcCsUFCWZh9pqEAtbdA2AkvPJIYcfHT78BOHl+7Rs586vn8NRWqblqJPSIPAbPqeIzrCYgqDFcP23ea47/ehRirtuK9Eesaf9m0xzWuOE1/XXvch2e+uVvQXI3h2Jhcq+kX9VrXoRjd5q3JgbK59aaHYFHccBMcW7pTS7jBz8FuT5Y8PjCsTFoQ0IrfoSMbAuBDZNW9CQ64D9fv4Gymu0sO+sIXd9nGMa434amFHFraineL2tJOtDwMr7qbkfWY25RiTFYd3w0PT+XDpsHGtR2dxagu1xz5OmoWbIR2qZ0INTJLu0x7Ud2s3LC1tjJ7dQ0I7EkTr3Gv2yXf4qBpiPraKLIXCSao+xk2+T7T2jrfIpzY3R5/TPOrQ/dF0m6vUxmZsmvV40wvt6yRhowdmFO1EmO8T75Kqxo6xx7xZpABWaKtKMCcAKCM+WZR8TxmLV3pWYIrqxoZwDl21vpsGUgmex3kFhFOsw8phO0czizFRzlOqAu1ysuTNc7uHF1BcQbLC1MfHmIlFaN0ZEb58RAvd7EnsTo2juAZTKkZrkM8X0fiOwqapDywTg/ghmD5Wu5PSFobTA1x0rXxbA34EA4qc5V+CKzUr0YyDyXqO2BEWib+6Wlprqebxuc1Lh8MtveypwZ0wkGCQSZFQdJfHzSNs5nnfUlCZgg+akMCzPav+juYsLa6yQMdzCc847vSNdUX2VsWgIHNV+ljSeUtYUioAkQBQCfzawpZxtHbPnxV5ly5l+15y5zRHKtIOS3uELun4KTM4Jy6Alqzaj8312Q0ps7uiIv2aRZNQ6J7pGSQFKKi/6FWS3vzkHz9Dvngj8UXtTPvcvs2WV4VacYoJnDcxr1MQyU3ShyU+Q2575qEbI9vmj+81dzKRcrVCPS+1jTJmB7VlGKvauTpm7gSTpSNmrJ5H8NBnIpzWz6BDG0ZzMx2RN6dUI3LrJoleD8ZBLO44P95GDU85ap/dpYXfjGr8FCPVGGSxtiO1rc80LuVc4dRqFYVMUB4eCum69YA/5ZMNSHYBBIZMQn2ASGJ0KveirJf6/CZ0peuY/ae9oUATxpU0VnFyO2w8eX91kq1rhKBJLlpdM3TxF41PISF/o6LUXAu5niFMEs7liCz+Cbt/+Bx+oh9WDKgdLD6YqxQXMiQS74xPIKB8bkPudRbH X-Forefront-Antispam-Report-Untrusted: CIP:172.205.89.229; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:nebula.arm.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230040)(36860700013)(82310400026)(7416014)(376014)(1800799024)(3122999003); DIR:OUT; SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR08MB10199 X-MS-Exchange-Transport-CrossTenantHeadersStripped: AM3PEPF0000A79B.eurprd04.prod.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: 14e15d3c-4172-444b-7ede-08ddf5e81dd9 X-Microsoft-Antispam: BCL:0; ARA:13230040|35042699022|82310400026|14060799003|36860700013|1800799024|376014|7416014|3122999003; X-Microsoft-Antispam-Message-Info: RxNkXqmlaVUn/U9WzpmJ7QkJse2ghj/rR4Fm7+HOYthbL8aA5tRtST8+pQTajEdG9YtF8kSGZ+88GuEYxhWIWXU7frBQcaaSoofHZVJnsOcRhxgRdrAZMCLmZK8vruk5fhIMgLBuWR0Ant1tC3o0ZbVwhiTIp402W/W3wGu8MgbeDkC3fUjCtFXvqwQ+DtpbnoeCpz/660/k29iDjp6mBV2lJT1ds2kojUf8cmc+T6quZDoK2xnvy1ObGJq7u7HqXpyWN/IyEmE3ORmXXb6Wn99WwfKGY6FePKjMv8ajAluVOoKYZLaBTt5ehxOBJgYVDD57yVw/6jcwdRR3WcgtmFwbjAvxIXFCWJsmSpRuqBbuo9aDYx4n0U0a/firn8BoLjgmoSrU5ngDJBJbRvScBqt5e+uGX3AdtU2hPQEZXk+vQ9n9TZPerkmb5TA559cjbS4qA6zmfVtkVz6ATOMMM0SHG3PEbjX1RkOhO+FnQZ4EdQ64/wf65tBtN0QmM+BnXlwya2PTuRNHwSGuzO5flWt6BDYiDsuHZfwQnPzwKCcOdXpW+dLeviILkf0M17LvzKcILoTRXnhX9Y1LjTVA3Tkfzah3qKnPsjp1TJTPjmz9QfZ0j5vl/5kXCsm42qm+y4YL1MRGRAQf1ZWEwgBkbLHw9eIGqr1SDN3xHC43d89yl36zTl+zP/mRI2eFO/Mw8lKP3LuiPxPmLszVAdQ4x4qyCNUK/FJzM5DFcoAA6+c5wavljf4bJ20ppragteyPRfJ8Obbf64wWIH88LA5YrLf0WttWhUbePnIsjGX4knVBhu1VSyZjw120DguJgZayL1t9RjuEPIB+UWvftwV2x0ghtAwVJFC3tSwfqrcGD9FGg256toRWrMUM/NWdgCTl+4/zPsuLj+iHE2sXVjOEP/ym8y5uIDpqNTSL5+1TgSxmaOLcR5mgtP4LaArspVv62U7nF7XXTB6/jFG3468oSPDqmIR1JMve5hC9G1P+3gvd8XH+xsf7/WcLm7C00t67Rw0pHQqMdQIDBdafW/GiB3tqmI1QBvOALRwF2wfSXCz5Kl1KDgERZ2J1m4RjhKNoWO6IRdl+lXiw3gVYwHPtV7RhUJJ9zFTHR20ZWuJo0D+7nLOoGagcertHmFjN/h5+eLmkPSBADm4Vtf2nEBpbIgZUcN5u/5Ls1/QOt+k2U6iuJ8QAVe/b39Y1nhAMqI0OFwNghoUj/rbm4/TcL7JmWMKzc+u2ZwjR2uTAqc8N6pm3K8SW4DUzw2GonIE+6iudoLYVcgn3Wm9fEjOTQb4nQPj8iNP6eO3lSV8O9CpEiaLGQsxDjK8L4bJFxaiphdTeuJeKddcuFU4b+epqmnNkCD2vDFsB+9QMKJUay7rP6yVw17lkDiZ6kO9ADLHS+HdLpY6pbbX39v4zjUI8g4PUq/xGUwhF8uGMYeaW2tHAm3kajPEgoHaz5H2RswWdRj40s9iALAc78+iXWujvZrSBm+VMPp/NWMLs4znQrTcAZm7RBf6zCmvxcCPUhnPZ9V7s X-Forefront-Antispam-Report: CIP:4.158.2.129; CTRY:GB; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:outbound-uk1.az.dlp.m.darktrace.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230040)(35042699022)(82310400026)(14060799003)(36860700013)(1800799024)(376014)(7416014)(3122999003); DIR:OUT; SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Sep 2025 12:46:20.7353 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: a3f93a14-1dc2-49b2-2302-08ddf5e833e3 X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[4.158.2.129]; Helo=[outbound-uk1.az.dlp.m.darktrace.com] X-MS-Exchange-CrossTenant-AuthSource: AM3PEPF0000A79B.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: GV2PR08MB7956 X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FORGED_SPF_HELO, GIT_PATCH_0, RCVD_IN_MSPIKE_H2, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_PASS, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org From: Alfie Richards This change refactors FMV handling in the frontend to allows greater reasoning about versions in shared code. This is needed for allowing target_clones and target_versions to be used together in a function set, as there is then two distinct concerns when encountering two declarations that previously were conflated: 1. Are these two declarations completely disjoint FMV declarations (ie. the sets of versions they define have no overlap). If so, they don't conflict so there is no need to merge and both can be pushed. 2. For two declarations that aren't completely disjoint, are they matching and therefore mergeable. (ie. two target_clone decls that define the same set of versions, or an un-annotated declaration, and a target_clones definition containing the default version). If so, continue to the existing merging logic to try to merge these and diagnose if it's not possible. If not, then diagnose the conflicting declarations. To do this the common_function_versions function has been renamed disjoint_function_versions (meaning, are the version sets defined by these two decl's completely distinct from each other). A new hook called same_function_version is introduces taking two string_slice's (each representing a single version) and determining if they define the same version. A new function, called diagnose_versioned_decls is added, which checks if two decls (with overlapping version sets) can be merged and diagnose when they cannot be (only in terms of the attributes, the existing logic is used to detect other mergeability conflicts like redefinition). This only effects targets with TARGET_HAS_FMV_TARGET_ATTRIBUTE set to false. (ie. aarch64 and riscv), the existing logic for i86 and ppc is unchanged. This also means the same function version hook is only used for aarch64 and riscv. gcc/ChangeLog: * attribs.h (common_function_versions): Removed. * attribs.cc (common_function_versions): Removed. * config/aarch64/aarch64.cc (aarch64_common_function_versions): Removed. (aarch64_same_function_versions): New function to check if two version strings imply the same version. (TARGET_OPTION_FUNCTION_VERSIONS): Removed. (TARGET_OPTION_SAME_FUNCTION_VERSIONS): New macro. * config/i386/i386.cc (TARGET_OPTION_FUNCTION_VERSIONS): Removed. * config/rs6000/rs6000.cc (TARGET_OPTION_FUNCTION_VERSIONS): Removed. * config/riscv/riscv.cc (riscv_same_function_versions): New function to check if two version strings imply the same version. (riscv_common_function_versions): Removed. (TARGET_OPTION_FUNCTION_VERSIONS): Removed. (TARGET_OPTION_SAME_FUNCTION_VERSIONS): New macro. * doc/tm.texi: Regenerated. * target.def: Remove common_version hook and add same_function_version hook. * doc/tm.texi.in: Ditto. * tree.cc (distinct_version_decls): New function. (mergeable_version_decls): Ditto. * tree.h (distinct_version_decls): New function. (mergeable_version_decls): Ditto. * hooks.h (hook_stringslice_stringslice_unreachable): New function. * hooks.cc (hook_stringslice_stringslice_unreachable): New function. gcc/cp/ChangeLog: * class.cc (resolve_address_of_overloaded_function): Updated to use dijoint_versions_decls instead of common_function_version hook. * decl.cc (decls_match): Refacture to use disjoint_version_decls and to pass through conflicting_version argument. (maybe_version_functions): Updated to use disjoint_version_decls instead of common_function_version hook. (duplicate_decls): Add logic to handle conflicting unmergable decls and improve diagnostics for conflicting versions. * decl2.cc (check_classfn): Updated to use disjoint_version_decls instead of common_function_version hook. --- gcc/attribs.cc | 67 ---------- gcc/attribs.h | 1 - gcc/config/aarch64/aarch64.cc | 25 ++-- gcc/config/i386/i386.cc | 3 - gcc/config/riscv/riscv.cc | 35 ++--- gcc/config/rs6000/rs6000.cc | 3 - gcc/cp/class.cc | 3 +- gcc/cp/decl.cc | 8 +- gcc/cp/decl2.cc | 2 +- gcc/doc/tm.texi | 9 +- gcc/doc/tm.texi.in | 2 +- gcc/hooks.cc | 7 + gcc/hooks.h | 1 + gcc/target.def | 21 ++- gcc/tree.cc | 243 ++++++++++++++++++++++++++++++++++ gcc/tree.h | 5 + 16 files changed, 310 insertions(+), 125 deletions(-) diff --git a/gcc/attribs.cc b/gcc/attribs.cc index c75fd1371fd..9efc327553f 100644 --- a/gcc/attribs.cc +++ b/gcc/attribs.cc @@ -1086,8 +1086,6 @@ make_attribute (string_slice name, string_slice arg_name, tree chain) return attr; } -/* Common functions used for target clone support. */ - /* Comparator function to be used in qsort routine to sort attribute specification strings to "target". */ @@ -1177,71 +1175,6 @@ sorted_attr_string (tree arglist) return ret_str; } - -/* This function returns true if FN1 and FN2 are versions of the same function, - that is, the target strings of the function decls are different. This assumes - that FN1 and FN2 have the same signature. */ - -bool -common_function_versions (tree fn1, tree fn2) -{ - tree attr1, attr2; - char *target1, *target2; - bool result; - - if (TREE_CODE (fn1) != FUNCTION_DECL - || TREE_CODE (fn2) != FUNCTION_DECL) - return false; - - attr1 = lookup_attribute ("target", DECL_ATTRIBUTES (fn1)); - attr2 = lookup_attribute ("target", DECL_ATTRIBUTES (fn2)); - - /* At least one function decl should have the target attribute specified. */ - if (attr1 == NULL_TREE && attr2 == NULL_TREE) - return false; - - /* Diagnose missing target attribute if one of the decls is already - multi-versioned. */ - if (attr1 == NULL_TREE || attr2 == NULL_TREE) - { - if (DECL_FUNCTION_VERSIONED (fn1) || DECL_FUNCTION_VERSIONED (fn2)) - { - if (attr2 != NULL_TREE) - { - std::swap (fn1, fn2); - attr1 = attr2; - } - auto_diagnostic_group d; - error_at (DECL_SOURCE_LOCATION (fn2), - "missing % attribute for multi-versioned %qD", - fn2); - inform (DECL_SOURCE_LOCATION (fn1), - "previous declaration of %qD", fn1); - /* Prevent diagnosing of the same error multiple times. */ - DECL_ATTRIBUTES (fn2) - = tree_cons (get_identifier ("target"), - copy_node (TREE_VALUE (attr1)), - DECL_ATTRIBUTES (fn2)); - } - return false; - } - - target1 = sorted_attr_string (TREE_VALUE (attr1)); - target2 = sorted_attr_string (TREE_VALUE (attr2)); - - /* The sorted target strings must be different for fn1 and fn2 - to be versions. */ - if (strcmp (target1, target2) == 0) - result = false; - else - result = true; - - XDELETEVEC (target1); - XDELETEVEC (target2); - - return result; -} - /* Make a dispatcher declaration for the multi-versioned function DECL. Calls to DECL function will be replaced with calls to the dispatcher by the front-end. Return the decl created. */ diff --git a/gcc/attribs.h b/gcc/attribs.h index b8b6838599c..c4a4fb0e50b 100644 --- a/gcc/attribs.h +++ b/gcc/attribs.h @@ -54,7 +54,6 @@ extern struct scoped_attributes * register_scoped_attributes (const scoped_attribute_specs &, bool = false); extern char *sorted_attr_string (tree); -extern bool common_function_versions (tree, tree); extern tree make_dispatcher_decl (const tree); extern bool is_function_default_version (const tree); extern void handle_ignored_attributes_option (vec *); diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 4a42735acc4..20ae37bdf7d 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -21160,18 +21160,23 @@ aarch64_get_function_versions_dispatcher (void *decl) return dispatch_decl; } -/* This function returns true if FN1 and FN2 are versions of the same function, - that is, the target_version attributes of the function decls are different. - This assumes that FN1 and FN2 have the same signature. */ +/* This function returns true if STR1 and STR2 are version strings for the same + function. */ bool -aarch64_common_function_versions (tree fn1, tree fn2) +aarch64_same_function_versions (string_slice str1, string_slice str2) { - if (TREE_CODE (fn1) != FUNCTION_DECL - || TREE_CODE (fn2) != FUNCTION_DECL) - return false; + enum aarch_parse_opt_result parse_res; + aarch64_fmv_feature_mask feature_mask1; + aarch64_fmv_feature_mask feature_mask2; + parse_res = aarch64_parse_fmv_features (str1, NULL, + &feature_mask1, NULL); + gcc_assert (parse_res == AARCH_PARSE_OK); + parse_res = aarch64_parse_fmv_features (str2, NULL, + &feature_mask2, NULL); + gcc_assert (parse_res == AARCH_PARSE_OK); - return (aarch64_compare_version_priority (fn1, fn2) != 0); + return feature_mask1 == feature_mask2; } /* Implement TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P. Use an opt-out @@ -32836,8 +32841,8 @@ aarch64_libgcc_floating_mode_supported_p #undef TARGET_EMIT_EPILOGUE_FOR_SIBCALL #define TARGET_EMIT_EPILOGUE_FOR_SIBCALL aarch64_expand_epilogue -#undef TARGET_OPTION_FUNCTION_VERSIONS -#define TARGET_OPTION_FUNCTION_VERSIONS aarch64_common_function_versions +#undef TARGET_OPTION_SAME_FUNCTION_VERSIONS +#define TARGET_OPTION_SAME_FUNCTION_VERSIONS aarch64_same_function_versions #undef TARGET_CHECK_TARGET_CLONE_VERSION #define TARGET_CHECK_TARGET_CLONE_VERSION aarch64_check_target_clone_version diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 5ef7c315091..b6c6e01d01d 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -28244,9 +28244,6 @@ ix86_libgcc_floating_mode_supported_p #undef TARGET_OPTION_PRINT #define TARGET_OPTION_PRINT ix86_function_specific_print -#undef TARGET_OPTION_FUNCTION_VERSIONS -#define TARGET_OPTION_FUNCTION_VERSIONS common_function_versions - #undef TARGET_CAN_INLINE_P #define TARGET_CAN_INLINE_P ix86_can_inline_p diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 182cefbc374..4a6a1161833 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -14080,6 +14080,23 @@ compare_fmv_features (const struct riscv_feature_bits &mask1, return 0; } +/* This function returns true if V1 and V2 specify the same function + version. */ + +bool +riscv_same_function_versions (string_slice v1, string_slice v2) +{ + struct riscv_feature_bits mask1, mask2; + int prio1, prio2; + + /* Invalid features should have already been rejected by this point so + providing no location should be okay. */ + parse_features_for_version (v1, UNKNOWN_LOCATION, mask1, prio1); + parse_features_for_version (v2, UNKNOWN_LOCATION, mask2, prio2); + + return compare_fmv_features (mask1, mask2, prio1, prio2) == 0; +} + /* Compare priorities of two version decls. Return: 1: mask1 is higher priority -1: mask2 is higher priority @@ -14104,20 +14121,6 @@ riscv_compare_version_priority (tree decl1, tree decl2) return compare_fmv_features (mask1, mask2, prio1, prio2); } -/* This function returns true if FN1 and FN2 are versions of the same function, - that is, the target_version attributes of the function decls are different. - This assumes that FN1 and FN2 have the same signature. */ - -bool -riscv_common_function_versions (tree fn1, tree fn2) -{ - if (TREE_CODE (fn1) != FUNCTION_DECL - || TREE_CODE (fn2) != FUNCTION_DECL) - return false; - - return riscv_compare_version_priority (fn1, fn2) != 0; -} - /* Checks if the function version specifying string STR parses correctly. If it is an invalid string, currently emits a diagnostic at LOC. Always returns true. */ @@ -15976,8 +15979,8 @@ riscv_prefetch_offset_address_p (rtx x, machine_mode mode) #undef TARGET_CHECK_TARGET_CLONE_VERSION #define TARGET_CHECK_TARGET_CLONE_VERSION riscv_check_target_clone_version -#undef TARGET_OPTION_FUNCTION_VERSIONS -#define TARGET_OPTION_FUNCTION_VERSIONS riscv_common_function_versions +#undef TARGET_OPTION_SAME_FUNCTION_VERSIONS +#define TARGET_OPTION_SAME_FUNCTION_VERSIONS riscv_same_function_versions #undef TARGET_MANGLE_DECL_ASSEMBLER_NAME #define TARGET_MANGLE_DECL_ASSEMBLER_NAME riscv_mangle_decl_assembler_name diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index d00d5f27121..1049c446c40 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -1730,9 +1730,6 @@ static const scoped_attribute_specs *const rs6000_attribute_table[] = #define TARGET_GET_FUNCTION_VERSIONS_DISPATCHER \ rs6000_get_function_versions_dispatcher -#undef TARGET_OPTION_FUNCTION_VERSIONS -#define TARGET_OPTION_FUNCTION_VERSIONS common_function_versions - #undef TARGET_HARD_REGNO_NREGS #define TARGET_HARD_REGNO_NREGS rs6000_hard_regno_nregs_hook #undef TARGET_HARD_REGNO_MODE_OK diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc index df8d3c9321e..b56cc518a11 100644 --- a/gcc/cp/class.cc +++ b/gcc/cp/class.cc @@ -9127,8 +9127,7 @@ resolve_address_of_overloaded_function (tree target_type, decls_match will return false as they are different. */ for (match = TREE_CHAIN (matches); match; match = TREE_CHAIN (match)) if (!decls_match (fn, TREE_PURPOSE (match)) - && !targetm.target_option.function_versions - (fn, TREE_PURPOSE (match))) + && !disjoint_version_decls (fn, TREE_PURPOSE (match))) break; if (match) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index f75e057c2ef..7927b4375ec 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -1212,7 +1212,7 @@ decls_match (tree newdecl, tree olddecl, bool record_versions /* = true */) if (types_match && !DECL_EXTERN_C_P (newdecl) && !DECL_EXTERN_C_P (olddecl) - && targetm.target_option.function_versions (newdecl, olddecl)) + && disjoint_version_decls (newdecl, olddecl)) { if (record_versions) maybe_version_functions (newdecl, olddecl); @@ -1295,7 +1295,7 @@ maybe_mark_function_versioned (tree decl) bool maybe_version_functions (tree newdecl, tree olddecl) { - if (!targetm.target_option.function_versions (newdecl, olddecl)) + if (!disjoint_version_decls (newdecl, olddecl)) return false; maybe_mark_function_versioned (olddecl); @@ -2107,6 +2107,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) /* Leave it to update_binding to merge or report error. */ return NULL_TREE; } + /* Check if the two decls are non-mergeable versioned decls. */ + else if (!TARGET_HAS_FMV_TARGET_ATTRIBUTE + && diagnose_versioned_decls (olddecl, newdecl)) + return error_mark_node; else { const char *errmsg = redeclaration_error_message (newdecl, olddecl); diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index f87d7d68547..dfaef30dbfc 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -877,7 +877,7 @@ check_classfn (tree ctype, tree function, tree template_parms) if (same_type_p (TREE_TYPE (TREE_TYPE (function)), TREE_TYPE (TREE_TYPE (fndecl))) && compparms (p1, p2) - && !targetm.target_option.function_versions (function, fndecl) + && !disjoint_version_decls (function, fndecl) && (!is_template || comp_template_parms (template_parms, DECL_TEMPLATE_PARMS (fndecl))) diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index d2b1e712628..218bf3abbde 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -10978,12 +10978,9 @@ changed via the optimize attribute or pragma, see @code{TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE} @end deftypefn -@deftypefn {Target Hook} bool TARGET_OPTION_FUNCTION_VERSIONS (tree @var{decl1}, tree @var{decl2}) -This target hook returns @code{true} if @var{DECL1} and @var{DECL2} are -versions of the same function. @var{DECL1} and @var{DECL2} are function -versions if and only if they have the same function signature and -different target specific attributes, that is, they are compiled for -different target machines. +@deftypefn {Target Hook} bool TARGET_OPTION_SAME_FUNCTION_VERSIONS (string_slice @var{fn1}, string_slice @var{fn2}) +This target hook returns @code{true} if the target/target-version strings +@var{fn1} and @var{fn2} imply the same function version. @end deftypefn @deftypefn {Target Hook} bool TARGET_CAN_INLINE_P (tree @var{caller}, tree @var{callee}) diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 30a9400f0f9..57653a133a6 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -7140,7 +7140,7 @@ with the target specific attributes. The default value is @code{','}. @hook TARGET_OPTION_OVERRIDE -@hook TARGET_OPTION_FUNCTION_VERSIONS +@hook TARGET_OPTION_SAME_FUNCTION_VERSIONS @hook TARGET_CAN_INLINE_P diff --git a/gcc/hooks.cc b/gcc/hooks.cc index 865820d80b1..820c81e31e4 100644 --- a/gcc/hooks.cc +++ b/gcc/hooks.cc @@ -27,6 +27,7 @@ #include "coretypes.h" #include "tm.h" #include "hooks.h" +#include "vec.h" /* Generic hook that does absolutely zappo. */ void @@ -593,3 +594,9 @@ hook_stringslice_locationtptr_true (string_slice, location_t *) { return true; } + +bool +hook_stringslice_stringslice_unreachable (string_slice, string_slice) +{ + gcc_unreachable (); +} diff --git a/gcc/hooks.h b/gcc/hooks.h index 08542d7a24e..a7021f532a5 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -139,5 +139,6 @@ extern opt_machine_mode hook_optmode_mode_uhwi_none (machine_mode, unsigned HOST_WIDE_INT); extern bool hook_stringslice_locationtptr_true (string_slice, location_t *); +extern bool hook_stringslice_stringslice_unreachable (string_slice, string_slice); #endif diff --git a/gcc/target.def b/gcc/target.def index 02172c52d20..b6f95f3ac7a 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -6925,19 +6925,14 @@ changed via the optimize attribute or pragma, see\n\ void, (void), hook_void_void) -/* This function returns true if DECL1 and DECL2 are versions of the same - function. DECL1 and DECL2 are function versions if and only if they - have the same function signature and different target specific attributes, - that is, they are compiled for different target machines. */ -DEFHOOK -(function_versions, - "This target hook returns @code{true} if @var{DECL1} and @var{DECL2} are\n\ -versions of the same function. @var{DECL1} and @var{DECL2} are function\n\ -versions if and only if they have the same function signature and\n\ -different target specific attributes, that is, they are compiled for\n\ -different target machines.", - bool, (tree decl1, tree decl2), - hook_bool_tree_tree_false) +/* This function returns true if FN1 and FN2 define the same version of a + function. */ +DEFHOOK +(same_function_versions, + "This target hook returns @code{true} if the target/target-version strings\n\ +@var{fn1} and @var{fn2} imply the same function version.", + bool, (string_slice fn1, string_slice fn2), + hook_stringslice_stringslice_unreachable) /* Function to determine if one function can inline another function. */ #undef HOOK_PREFIX diff --git a/gcc/tree.cc b/gcc/tree.cc index 2e114d01110..cad57fedc7a 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -15490,6 +15490,249 @@ get_target_version (const tree decl) .strip (); } +/* Returns true if FN1 and FN2 define dijoint function versions in an FMV + function set. That is, the two declarations are completely non-overlapping. + For target_version semantics, that means if one is a target clone and one is + a target version, the target_version must not be defined by the target_clone, + and for two target_clones, they must not define any of the same version. + + FN1 and FN2 should be function decls. */ + +bool +disjoint_version_decls (tree fn1, tree fn2) +{ + if (TREE_CODE (fn1) != FUNCTION_DECL + || TREE_CODE (fn2) != FUNCTION_DECL) + return false; + + if (TARGET_HAS_FMV_TARGET_ATTRIBUTE) + { + tree attr1 = lookup_attribute ("target", DECL_ATTRIBUTES (fn1)); + tree attr2 = lookup_attribute ("target", DECL_ATTRIBUTES (fn2)); + + /* At least one function decl should have the target attribute + specified. */ + if (attr1 == NULL_TREE && attr2 == NULL_TREE) + return false; + + /* Diagnose missing target attribute if one of the decls is already + multi-versioned. */ + if (attr1 == NULL_TREE || attr2 == NULL_TREE) + { + if (DECL_FUNCTION_VERSIONED (fn1) || DECL_FUNCTION_VERSIONED (fn2)) + { + if (attr2 != NULL_TREE) + { + std::swap (fn1, fn2); + attr1 = attr2; + } + auto_diagnostic_group d; + error_at (DECL_SOURCE_LOCATION (fn2), + "missing % attribute for multi-versioned %qD", + fn2); + inform (DECL_SOURCE_LOCATION (fn1), + "previous declaration of %qD", fn1); + /* Prevent diagnosing of the same error multiple times. */ + DECL_ATTRIBUTES (fn2) + = tree_cons (get_identifier ("target"), + copy_node (TREE_VALUE (attr1)), + DECL_ATTRIBUTES (fn2)); + } + return false; + } + + char *target1 = sorted_attr_string (TREE_VALUE (attr1)); + char *target2 = sorted_attr_string (TREE_VALUE (attr2)); + + /* The sorted target strings must be different for fn1 and fn2 + to be versions. */ + bool result = strcmp (target1, target2) != 0; + + XDELETEVEC (target1); + XDELETEVEC (target2); + + return result; + } + else + { + /* As this is symmetric, can remove the case where fn2 is target clone + and fn1 is target version by swapping here. */ + if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (fn2))) + std::swap (fn1, fn2); + + if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (fn1))) + { + auto_vec fn1_versions = get_clone_versions (fn1); + /* fn1 is target_clone. */ + if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (fn2))) + { + /* Both are target_clone. */ + auto_vec fn2_versions = get_clone_versions (fn2); + for (string_slice v1 : fn1_versions) + { + for (string_slice v2 : fn2_versions) + if (targetm.target_option.same_function_versions (v1, v2)) + return false; + } + return true; + } + else + { + string_slice v2 = get_target_version (fn2); + + /* target and target_clones is always conflicting for target + semantics. */ + if (TARGET_HAS_FMV_TARGET_ATTRIBUTE) + return false; + + /* Only fn1 is target clone. */ + if (!v2.is_valid ()) + v2 = "default"; + for (string_slice v1 : fn1_versions) + if (targetm.target_option.same_function_versions (v1, v2)) + return false; + return true; + } + } + else + { + /* Both are target_version. */ + string_slice v1 = get_target_version (fn1); + string_slice v2 = get_target_version (fn2); + + if (!v1.is_valid () && !v2.is_valid ()) + return false; + + if (!v1.is_valid ()) + v1 = "default"; + if (!v2.is_valid ()) + v2 = "default"; + + if (targetm.target_option.same_function_versions (v1, v2)) + return false; + + return true; + } + } +} + +/* Check if the target_version/target_clones attributes are mergeable + for two decls, and if so returns false. + If they aren't mergeable, diagnose this and return true. + Only works for target_version semantics. */ +bool +diagnose_versioned_decls (tree old_decl, tree new_decl) +{ + gcc_assert (!TARGET_HAS_FMV_TARGET_ATTRIBUTE); + + string_slice old_target_attr = get_target_version (old_decl); + string_slice new_target_attr = get_target_version (new_decl); + + tree old_target_clones_attr = lookup_attribute ("target_clones", + DECL_ATTRIBUTES (old_decl)); + tree new_target_clones_attr = lookup_attribute ("target_clones", + DECL_ATTRIBUTES (new_decl)); + + /* If none of these are annotated, then it is mergeable. */ + if (!old_target_attr.is_valid () + && !old_target_attr.is_valid () + && !old_target_clones_attr + && !new_target_clones_attr) + return false; + + /* If fn1 is unnanotated and fn2 contains default, then is mergeable. */ + if (!old_target_attr.is_valid () + && !old_target_clones_attr + && is_function_default_version (new_decl)) + return false; + + /* If fn2 is unnanotated and fn1 contains default, then is mergeable. */ + if (!new_target_attr.is_valid () + && !new_target_clones_attr + && is_function_default_version (old_decl)) + return false; + + /* In the case where both are annotated with target_clones, only mergeable if + the two sets of target_clones imply the same set of versions. */ + if (old_target_clones_attr && new_target_clones_attr) + { + auto_vec fn1_versions = get_clone_versions (old_decl); + auto_vec fn2_versions = get_clone_versions (new_decl); + + bool mergeable = true; + + if (fn1_versions.length () != fn2_versions.length ()) + mergeable = false; + + /* Check both inclusion directions. */ + for (auto fn1v : fn1_versions) + { + bool matched = false; + for (auto fn2v : fn2_versions) + if (targetm.target_option.same_function_versions (fn1v, fn2v)) + matched = true; + if (!matched) + mergeable = false; + } + + for (auto fn2v : fn2_versions) + { + bool matched = false; + for (auto fn1v : fn1_versions) + if (targetm.target_option.same_function_versions (fn1v, fn2v)) + matched = true; + if (!matched) + mergeable = false; + } + + if (!mergeable) + { + error_at (DECL_SOURCE_LOCATION (new_decl), + "%qD conflicts with overlapping % " + "declaration", + new_decl); + inform (DECL_SOURCE_LOCATION (old_decl), + "previous declaration of %qD", old_decl); + return true; + } + + return false; + } + + /* If olddecl is target clones and newdecl is a target_version. + As they are not distinct this implies newdecl redefines a version of + olddecl. Not mergeable. */ + if (new_target_clones_attr) + { + gcc_assert (old_target_attr.is_valid ()); + + error_at (DECL_SOURCE_LOCATION (new_decl), + "%qD conflicts for version %qB", + new_decl, &old_target_attr); + inform (DECL_SOURCE_LOCATION (old_decl), + "previous declaration of %qD", + old_decl); + return true; + } + + if (old_target_clones_attr) + { + gcc_assert (new_target_attr.is_valid ()); + + error_at (DECL_SOURCE_LOCATION (new_decl), + "%qD conflicts with a previous declaration for version %qB", + new_decl, &new_target_attr); + inform (DECL_SOURCE_LOCATION (old_decl), + "previous declaration of %qD", + old_decl); + return true; + } + + /* The only remaining case is two target_version annotated decls. Must + be mergeable as otherwise are distinct. */ + return false; +} + void tree_cc_finalize (void) { diff --git a/gcc/tree.h b/gcc/tree.h index b22dce5214a..b1d14341666 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -7116,4 +7116,9 @@ extern auto_vec get_clone_versions extern auto_vec get_clone_attr_versions (const tree, int *, bool = true); +/* Checks if two decls define any overlapping versions. */ +extern bool disjoint_version_decls (tree, tree); +/* Checks if two overlapping decls are not mergeable. */ +extern bool diagnose_versioned_decls (tree, tree); + #endif /* GCC_TREE_H */ From patchwork Wed Sep 17 12:44:55 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alfie Richards X-Patchwork-Id: 120423 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6B662385829B for ; Wed, 17 Sep 2025 12:47:49 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6B662385829B Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=selector1 header.b=a20Hxf0e; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=selector1 header.b=a20Hxf0e X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from PA4PR04CU001.outbound.protection.outlook.com (mail-francecentralazon11013068.outbound.protection.outlook.com [40.107.162.68]) by sourceware.org (Postfix) with ESMTPS id C9DD13858C60 for ; Wed, 17 Sep 2025 12:46:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C9DD13858C60 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org C9DD13858C60 Authentication-Results: server2.sourceware.org; arc=pass smtp.remote-ip=40.107.162.68 ARC-Seal: i=3; a=rsa-sha256; d=sourceware.org; s=key; t=1758113186; cv=pass; b=hAlu5SpR3k9JwNF/e24baXh5xfFbTcZFuYRz8L+VBPZ6pzT5LkTtDeLseIcBZfefcmMwp9cXrGG3uk+P201LhpHw+GrtzbISc0pprOluBhO5MpNWKgkdlAg+mHtx02utnbZIgRn4htmvERYill2EX6smYOzVkGxrx5p0wGKlCy8= ARC-Message-Signature: i=3; a=rsa-sha256; d=sourceware.org; s=key; t=1758113186; c=relaxed/simple; bh=0n7ZcCdYAToGa1VSM/CoM8vVchk+kHlkdlTfz5zka/E=; h=DKIM-Signature:DKIM-Signature:From:To:Subject:Date:Message-ID: MIME-Version; b=n6fEQVTaxg6ih/6cUL2ixGfL8Fdr1SDeks/K2k+tsAuG/sdb5jVcLdvZE4UMZLK0ZIS0o38Z08LprtimT9Ueq2h6ywo6/Z621voCEVaRYK8EVyc4UiEPH0C34ENwZqDuIrOBLFU08HFAoSmuutTjVpMJ54cwOFjtOvhzdf3J0G4= ARC-Authentication-Results: i=3; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C9DD13858C60 ARC-Seal: i=2; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=pass; b=DVa4VS5ii7BqU4C3WbmX/zwWtQNHDH2v1tDeQ3+iDbnHs1pMGnPjG76ZEO5+ucMXLWYgMfwOfNHJFa04px/iiCUmPM/7EVCaaQSz1ROvzB0IxpWd3nXBeT6ngbYfGu+zJ7dhEnW9LEiE5vSlQerGBQ7KBppT41pI9zUf5aAFGf+/NQ/Ky9zoxbUgH/ii8EiZhE1DWsFUGWTkKwC9yrouoleWYKEvzVKcg0Vby3w8QdHwNkorH4cvPlRsZ8puliyw6ESCPRRYmFLvSlxjyduC5SgW+OyCTWQIrgzno7La6mbmHsYisHBmw6in5u/ANqKbFIpzurKnI0FsmxCsfq9GUw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=5Wp2O2IOMLqkr4kHVC8jfd0d1wxjtDQGWYDWEhLr9r0=; b=Em4pIocbavWqzKt4aU7vocYpxmw6TGoAZQrKcioUjHhNE+JTjjg3H/I03IotD47AxMT3dWDUGqg7kYO59Q/8vqZcYg21mtHcaDQvOl85+qAnRtfamgrGp6C9OsTOuVF39jGDrNqhWIf8P4aln5Ed6vSihHG0GB2JfE5d/Eg5RWCc+rQAbwYtTcC4Fsd3nu6UhMw0mawKO6uexnH1MZr+GQx0arYyJdq1Vh5MecgFl1oTty/GlTgjFKzFF/EU3wNGQT9SoodSs7z1Ubsz1LBmvoyfVt//0i7Fve9JCb+fXsnVejz52tAok9Kxk5JGp3zu4FsonKVYW/HLLNPoFpbdSA== ARC-Authentication-Results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 4.158.2.129) smtp.rcpttodomain=gcc.gnu.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=pass (signature was verified) header.d=arm.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dmarc=[1,1,header.from=arm.com]) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=arm.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5Wp2O2IOMLqkr4kHVC8jfd0d1wxjtDQGWYDWEhLr9r0=; b=a20Hxf0eRWaDgz0Bk3V3dRTu0WJxRWNB1YHTmu+SVzpMnfUm9Q6EnbrrJ5gkmKtB0V5lFlmq+8SBCm5YZ731SP1KnT7mvSegPQ45t4SUqYQVcrC55ZLVCaGOJ5noFjnDIhRD+N7vua4NV0F9kiaB/tFoxCElr/9BVEaxp2ec5FM= Received: from CWLP123CA0269.GBRP123.PROD.OUTLOOK.COM (2603:10a6:400:1d5::12) by DU4PR08MB11005.eurprd08.prod.outlook.com (2603:10a6:10:576::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9115.22; Wed, 17 Sep 2025 12:46:17 +0000 Received: from AM3PEPF0000A78E.eurprd04.prod.outlook.com (2603:10a6:400:1d5:cafe::c5) by CWLP123CA0269.outlook.office365.com (2603:10a6:400:1d5::12) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.13 via Frontend Transport; Wed, 17 Sep 2025 12:46:17 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 4.158.2.129) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=arm.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 4.158.2.129 as permitted sender) receiver=protection.outlook.com; client-ip=4.158.2.129; helo=outbound-uk1.az.dlp.m.darktrace.com; pr=C Received: from outbound-uk1.az.dlp.m.darktrace.com (4.158.2.129) by AM3PEPF0000A78E.mail.protection.outlook.com (10.167.16.117) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Wed, 17 Sep 2025 12:46:17 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=aGGasMUgS8tnOdlOUiUodp7knmVZx+y201BV4XYYHZteSA3PtaIAl2wF4xoI10vjSw7Jc9WRvmbo2ky5OrkHvSDmQ5/2om21Cgpx3Ml/s4TC/jUwiuDo0HQ2sxVS+dQdugwfAx2w8Ju8vrJ+Jdu0xCFUEzCjKBYeBYn+u9S42wM7ZRu08r0X9ScTTFNvRrnSYn3L7lIXbPQgLNlcpKmepvGcMPi2zCIeqss9g86OUA+YGRdAKTITT2ucPol9FBotRI5W5ykJTd3qfr7v+UPUSfHZVcVgwTJpkB5ErA3jJr48F7A08xDfOxIK1FwNOn3A9K1jfB2+at1Ua255DNM8kA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=5Wp2O2IOMLqkr4kHVC8jfd0d1wxjtDQGWYDWEhLr9r0=; b=M09rm/qu0AO4auR/y0bnPYD4rIkMyikVRdsmQHo1Q95gtJUT+PBN1eQO+HFZEapZcZuIbfgDwdQsHVyXgsWoWGhgP5dri/zjQPagsNas5y1JrT8deh9sqDE0972Qik03YWylDpRvPJlFPpuvFJCc1yLlOOtsh3OEV3Ll+zyJjXfzXRMCvd2A3Pyl8b72qPV+30csZxffUh+mLi6nhveONSuV3gXHXjsRWigEmwgXOosNvl/ffDJQJ5Nw+iw4LavCTLyZYg/AVwq0ZTGBwyvWpc3q3Z0VlOTDKs0C4QnCOjeXSbkqECo5y8usYdokh+BCuiRlrpwg/J8I8mpt43N4rw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 172.205.89.229) smtp.rcpttodomain=gcc.gnu.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=arm.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5Wp2O2IOMLqkr4kHVC8jfd0d1wxjtDQGWYDWEhLr9r0=; b=a20Hxf0eRWaDgz0Bk3V3dRTu0WJxRWNB1YHTmu+SVzpMnfUm9Q6EnbrrJ5gkmKtB0V5lFlmq+8SBCm5YZ731SP1KnT7mvSegPQ45t4SUqYQVcrC55ZLVCaGOJ5noFjnDIhRD+N7vua4NV0F9kiaB/tFoxCElr/9BVEaxp2ec5FM= Received: from AS9PR01CA0035.eurprd01.prod.exchangelabs.com (2603:10a6:20b:542::14) by DU5PR08MB10516.eurprd08.prod.outlook.com (2603:10a6:10:528::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9115.22; Wed, 17 Sep 2025 12:45:44 +0000 Received: from AM3PEPF0000A797.eurprd04.prod.outlook.com (2603:10a6:20b:542:cafe::25) by AS9PR01CA0035.outlook.office365.com (2603:10a6:20b:542::14) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.13 via Frontend Transport; Wed, 17 Sep 2025 12:46:02 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 172.205.89.229) smtp.mailfrom=arm.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 172.205.89.229 as permitted sender) receiver=protection.outlook.com; client-ip=172.205.89.229; helo=nebula.arm.com; pr=C Received: from nebula.arm.com (172.205.89.229) by AM3PEPF0000A797.mail.protection.outlook.com (10.167.16.102) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.9137.12 via Frontend Transport; Wed, 17 Sep 2025 12:45:44 +0000 Received: from AZ-NEU-EXJ02.Arm.com (10.240.25.139) by AZ-NEU-EX06.Arm.com (10.240.25.134) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Wed, 17 Sep 2025 12:44:58 +0000 Received: from AZ-NEU-EX05.Arm.com (10.240.25.133) by AZ-NEU-EXJ02.Arm.com (10.240.25.139) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.2562.27; Wed, 17 Sep 2025 12:44:58 +0000 Received: from ip-10-248-139-135.eu-west-1.compute.internal (10.248.139.135) by mail.arm.com (10.240.25.133) with Microsoft SMTP Server id 15.1.2507.39 via Frontend Transport; Wed, 17 Sep 2025 12:44:58 +0000 From: To: , CC: , , , , , , , , , , , , , Alfie Richards Subject: [PATCH v11 11/13] c: Add target_version attribute support. Date: Wed, 17 Sep 2025 12:44:55 +0000 Message-ID: <20250917124456.170437-4-alfie.richards@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250917124456.170437-1-alfie.richards@arm.com> References: <20250917124456.170437-1-alfie.richards@arm.com> MIME-Version: 1.0 X-EOPAttributedMessage: 1 X-MS-TrafficTypeDiagnostic: AM3PEPF0000A797:EE_|DU5PR08MB10516:EE_|AM3PEPF0000A78E:EE_|DU4PR08MB11005:EE_ X-MS-Office365-Filtering-Correlation-Id: 126d481e-808d-45e0-c3f4-08ddf5e831ca x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; ARA:13230040|1800799024|36860700013|82310400026|376014|7416014; X-Microsoft-Antispam-Message-Info-Original: xphRJGqkAYCAlRz+4r6JfRdxYm9bPd8nDSMPbgsa1ESq6FPmcP469RMNwIaKqSPmJkMN37xV6pVxvXmYH1yVQ/wI6/0Ca2esr7nNdPCpBkYIfc/WEI7U2ENFf2cZxc3QkZF/wIo2/MJ0t+cGUiSJdFKjnDAXBvK2Y6fwPLDv7SiC2xYcMzmwe6Fmvn9v1RJv7PuvuFVTaabxr/xYzKB9RmHTP6aG4EW++OjF+dE4VHTZXELiEfvKPunHs+PcFrbS3/RSWncHZc8SEuSO3ltydAfzSxO1yc2OUyAqJk7IMcJjWv4SRNl/7G6V8UqRDzFQyG99JtCmhdI994pkbdiXHDvKsDOM14DeJvKbbAIag87vqHZAs9tuj5EQ9j4dVGl4hIR7U2JtP/kazl0GjMNhlGz6NVRb46T7K7xBKuCZStp54qCNUVddR4UZcs6fMSuEWDzOrW9iEUjN7LIVQvgR8oGwwUaAZCDBQZPBmdIjtIJ5oA+2TOCywWAntTb+ilgZYC8ILkeN97Qe+cCnpKH66eu+BTG/a1Az+SZD5b0Dls6lFXy6tZ4FAQalE1VIdnlBQQGyBH8Y6XbyGC+2YVBpWyUB3QXVxyPQGnVbSfkjRSP5AohQzvAGupCnvVa+0sS3tcdQ/d3qIpgNd1wFZ/SLOhr2vX9hCWTnAz/0Tj0rEnlEnxe8AoWKOfDvu3hX3q9HcTlwl/weZndv9ljbkZTo3bmp/J7SI6/O+cvsqEAVXpK2g8hBL21l2dZAGrZkClAZElI5S+SkpF3CWQT/tMIihMtbCA07lX0+WRaLZTQlPTP7JzKzb6+rGwNUxB6NIRpr2IRGiSw0n12BMQuHhVJ7EknqRCDZYoEjUZRS7beIZaYVCJSqNKTTgsAtn/4ws3NkNXA3Zm53fgEbWXp7XTa8o3wDIaryA7YZ/SBondUzWB3QwmA26HUqXLwIm79qx90q+jKqGXN4kiRSuqzZlYOaBRWAYvg137prD2F6TkkM96NX1iZN3NhWr10XZCGQNLmIzxIiqE+SSz0uzhiZodcE1uq7cDUfw5eM45wHivLH1b0B3dY7LLuLFYgg8XU2sacbb/LsMKMzRuNrcaGQi8BKi7IG9cRg48fvEXS+pQgS3MnFSUNnukDUAcPEaBpSUD07LaWPpfx4leno/wb70sswlMWCtDnC90XMwAtujCWob1axbm3sHHhPSvzodTACxfNLrcYInty6c2uqfF7k3vHMzBd986WKowaTI1vr31644xaSu+whEsrtrQJPy3/JOg/yOK21PGtIBlPV+hZd8yuPVrZr6mldRxH95Xh5dCxstDbb8HAQWYssZfO4t6x5DMXFSuhhPIf1BZEjGBCHq15CzJNuoiwkXx+yeV8Otq/tPw0kADDoYCFaz2W1pwXGxcISl/52SnG6Olo+nardIXlZUNmTJoLE3f66gQuKJ7iqofWsADNoVc8Fn2fzCisO9gmvr9jC9NxOoiq6zVyaNHMP5g== X-Forefront-Antispam-Report-Untrusted: CIP:172.205.89.229; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:nebula.arm.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230040)(1800799024)(36860700013)(82310400026)(376014)(7416014); DIR:OUT; SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU5PR08MB10516 X-MS-Exchange-Transport-CrossTenantHeadersStripped: AM3PEPF0000A78E.eurprd04.prod.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: 20f066e3-0bf8-40d2-bdc7-08ddf5e81e04 X-Microsoft-Antispam: BCL:0; ARA:13230040|35042699022|82310400026|14060799003|1800799024|36860700013|7416014|376014|13003099007; X-Microsoft-Antispam-Message-Info: m3FvNWjnul8OTzjYsjydBhIw8l/eQaTUmCYQBTEzLUl0hCQvL2d1DVzpG2rRCo2iyDD0thp1EeQG3SiXyPNsfyLsru+yyCbSIm71xVFNe6DUgl0rrz/zkpyKCiMhsSvq14INEaxbS2PrHqMeTutjbcmNli19SVBwTkwxthdPZ/zPC09V5RTUfmispyQxaiO1y4SIbCIUOcMsPlGAYkC7/nWDDXtVYTohRtSBXKgQrRh1AZInp++i2i8A+Rh8NSHvajE6T1TLCIb+HJYU+lUmQc9D5jy86ccwBYUU9WUIwAtqwtx0FzEz00GBn2UvpF3nEQ5NFf/m8ZQKUtVp6+C5ZrNz3GK6mYmcEiS6jn70qO8Ri372DrwdSiQiOtDue2fp2VKFySYcjwD+YvBJGXeDG0bHVXLh7xUmXQU+L7cJ/irpoH8xPsOyDKjUvfceeXl4TILW94G6si8QY95KhK5Uea/HINPz6J3s+8bX1BViiCbfaDLQ7SQEmraPWDdDjoYw2WdxKGZHLNMpytipfRSCRznazaGnMOB/EX8Md8kyODKKj1K+k3lfNjxTJt/eyLZA0sdtPS4EvNs3eor9asy+gIzCyBJGw9QO8GknvFQiTCnfwo/y26jGl5iLzry3b2nA/WmWg0CTXS1WgIA7tuDq9MjKzyiRuk79lOV5q6ZwmgSDMrY0DEhTYbu4hD1coSTY2gwcv2HUZUwdAPz3KPGGv25siZxpIO0zOi18p916re+qKsekxwQh3fguwkx/0MVSv2N8evA8VfPXHC/vCbll5Xgpa3x+wEP92N2vV2exMCNwy+IBdLg5xOaiIDpo8dU/s3sQ2cf48I8fqaAmOCu+BL7DoVfszYGnb+k83VFC+HouVGKHWFKe7AugStP69EtJX++Mraw2h7X6f5MwwAsjWfihrHs7nJ4ccgw2OreSFRrQojUEniWH40shvL+GG/vq4xk7vmtr3oXsQRuYcV65zc4oEFsdzYLIuRWPZiUSKhBQ/I1MyQhN69ail8f65HpSFkI+5SmRIbHSn3lbc9G0zvqYBX1qVdO8XOo0qOLPBlnomNWy/FKi9XLfi7aFhxI+iRSUTRN3a6YQy9l+GSTki9E2gOoJZOFoqtJUKSZlWcTcmyRdxU4B4mEHJN6725yZR+RLF5OhnMCGf3sC663ET2kkMCnfePSMXtXRXXOGdOM75aO6kTxzsKjKG+mUa0YnXGPgloKCkNKo+5riZJkYGzvmwCtEZcMnKuXXe8NvD2F82V4J9xGuzXsCzxQ64JDEHp7e/QfOyqfZb3RMT3FCY034rV7vbEJ5Oc2Vhd1n1aIjRoZ+aETNybx7q2+URVJ9VtRpZXjhB9a/GvFU+q1UpRZNbBEb98WB+njKEz+XtvcQSII7LflwLGkD0pfQDDUW9TgyT2/TAcjgCIWn1kIbr9N6vmc5ki81ElAuYAHOLOnM1nFJVQ6imHibjVQ+SDKO+q33ao8AeZ267n2uVpvvYw== X-Forefront-Antispam-Report: CIP:4.158.2.129; CTRY:GB; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:outbound-uk1.az.dlp.m.darktrace.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230040)(35042699022)(82310400026)(14060799003)(1800799024)(36860700013)(7416014)(376014)(13003099007); DIR:OUT; SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Sep 2025 12:46:17.2158 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 126d481e-808d-45e0-c3f4-08ddf5e831ca X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[4.158.2.129]; Helo=[outbound-uk1.az.dlp.m.darktrace.com] X-MS-Exchange-CrossTenant-AuthSource: AM3PEPF0000A78E.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU4PR08MB11005 X-Spam-Status: No, score=-10.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FORGED_SPF_HELO, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_MSPIKE_H2, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_PASS, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org From: Alfie Richards This commit introduces support for the target_version attribute in the c frontend, following the behavior defined in the Arm C Language Extension. Key changes include: - During pushdecl, the compiler now checks whether the current symbol is part of a multiversioned set. - New versions are added to the function multiversioning (FMV) set, and the symbol binding is updated to include the default version (if present). This means the binding for a multiversioned symbol will always reference the default version (if present), as it defines the scope and signature for the entire set. - Pre-existing versions are merged with their previous version (or diagnosed). - Lookup logic is adjusted to prevent resolving non-default versions. - start_decl and start_function are updated to handle marking and mangling of versioned functions. - c_parse_final_cleanups now includes a call to process_same_body_aliases. This has no functional impact other than setting cpp_implicit_aliases_done on all nodes, which is necessary for certain shared FMV logic. gcc/c/ChangeLog: * c-decl.cc (maybe_mark_function_versioned): New function. (merge_decls): Preserve DECL_FUNCTION_VERSIONED in merging. (duplicate_decls): Add check and diagnostic for unmergable version decls. (pushdecl): Add FMV target_version logic. (lookup_name): Don't resolve non-default versions. (start_decl): Mark and mangle versioned functions. (start_function): Mark and mangle versioned functions. (c_parse_final_cleanups): Add call to process_same_body_aliases. gcc/testsuite/ChangeLog: * gcc.target/aarch64/mv-1.c: New test. * gcc.target/aarch64/mv-and-mvc1.c: New test. * gcc.target/aarch64/mv-and-mvc2.c: New test. * gcc.target/aarch64/mv-and-mvc3.c: New test. * gcc.target/aarch64/mv-and-mvc4.c: New test. * gcc.target/aarch64/mv-symbols1.c: New test. * gcc.target/aarch64/mv-symbols10.c: New test. * gcc.target/aarch64/mv-symbols11.c: New test. * gcc.target/aarch64/mv-symbols12.c: New test. * gcc.target/aarch64/mv-symbols13.c: New test. * gcc.target/aarch64/mv-symbols14.c: New test. * gcc.target/aarch64/mv-symbols2.c: New test. * gcc.target/aarch64/mv-symbols3.c: New test. * gcc.target/aarch64/mv-symbols4.c: New test. * gcc.target/aarch64/mv-symbols5.c: New test. * gcc.target/aarch64/mv-symbols6.c: New test. * gcc.target/aarch64/mv-symbols7.c: New test. * gcc.target/aarch64/mv-symbols8.c: New test. * gcc.target/aarch64/mv-symbols9.c: New test. * gcc.target/aarch64/mvc-symbols1.c: New test. * gcc.target/aarch64/mvc-symbols2.c: New test. * gcc.target/aarch64/mvc-symbols3.c: New test. * gcc.target/aarch64/mvc-symbols4.c: New test. --- gcc/c/c-decl.cc | 112 ++++++++++++++++++ gcc/testsuite/gcc.target/aarch64/mv-1.c | 43 +++++++ .../gcc.target/aarch64/mv-and-mvc1.c | 37 ++++++ .../gcc.target/aarch64/mv-and-mvc2.c | 28 +++++ .../gcc.target/aarch64/mv-and-mvc3.c | 40 +++++++ .../gcc.target/aarch64/mv-and-mvc4.c | 37 ++++++ .../gcc.target/aarch64/mv-symbols1.c | 38 ++++++ .../gcc.target/aarch64/mv-symbols10.c | 42 +++++++ .../gcc.target/aarch64/mv-symbols11.c | 16 +++ .../gcc.target/aarch64/mv-symbols12.c | 27 +++++ .../gcc.target/aarch64/mv-symbols13.c | 28 +++++ .../gcc.target/aarch64/mv-symbols14.c | 34 ++++++ .../gcc.target/aarch64/mv-symbols2.c | 28 +++++ .../gcc.target/aarch64/mv-symbols3.c | 27 +++++ .../gcc.target/aarch64/mv-symbols4.c | 31 +++++ .../gcc.target/aarch64/mv-symbols5.c | 36 ++++++ .../gcc.target/aarch64/mv-symbols6.c | 20 ++++ .../gcc.target/aarch64/mv-symbols7.c | 47 ++++++++ .../gcc.target/aarch64/mv-symbols8.c | 47 ++++++++ .../gcc.target/aarch64/mv-symbols9.c | 44 +++++++ .../gcc.target/aarch64/mvc-symbols1.c | 25 ++++ .../gcc.target/aarch64/mvc-symbols2.c | 15 +++ .../gcc.target/aarch64/mvc-symbols3.c | 19 +++ .../gcc.target/aarch64/mvc-symbols4.c | 12 ++ 24 files changed, 833 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-and-mvc1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-and-mvc2.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-and-mvc3.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-and-mvc4.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols10.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols11.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols12.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols13.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols14.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols2.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols3.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols4.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols5.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols6.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols7.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols8.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-symbols9.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mvc-symbols1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mvc-symbols2.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mvc-symbols3.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mvc-symbols4.c diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index b122e82bfc4..2d6fd9be2cd 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -2088,6 +2088,29 @@ previous_tag (tree type) return NULL_TREE; } +/* Subroutine to mark functions as versioned when using the attribute + 'target_version'. */ + +static void +maybe_mark_function_versioned (tree decl) +{ + if (!DECL_FUNCTION_VERSIONED (decl)) + { + /* We need to insert function version now to make sure the correct + pre-mangled assembler name is recorded. */ + cgraph_node *node = cgraph_node::get_create (decl); + + if (!node->function_version ()) + node->insert_new_function_version (); + + DECL_FUNCTION_VERSIONED (decl) = 1; + + tree mangled_name + = targetm.mangle_decl_assembler_name (decl, DECL_NAME (decl)); + SET_DECL_ASSEMBLER_NAME (decl, mangled_name); + } + } + /* Subroutine of duplicate_decls. Compare NEWDECL to OLDDECL. Returns true if the caller should proceed to merge the two, false if OLDDECL should simply be discarded. As a side effect, issues @@ -2507,6 +2530,10 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, "but not here"); } } + /* Check if these are unmergable overlapping FMV declarations. */ + if (!TARGET_HAS_FMV_TARGET_ATTRIBUTE + && diagnose_versioned_decls (olddecl, newdecl)) + return false; } else if (VAR_P (newdecl)) { @@ -2973,6 +3000,12 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) if (TREE_CODE (newdecl) == FUNCTION_DECL) { + if (DECL_FUNCTION_VERSIONED (olddecl) + || DECL_FUNCTION_VERSIONED (newdecl)) + { + maybe_mark_function_versioned (olddecl); + maybe_mark_function_versioned (newdecl); + } /* If we're redefining a function previously defined as extern inline, make sure we emit debug info for the inline before we throw it away, in case it was inlined into a function that @@ -3372,6 +3405,53 @@ pushdecl (tree x) TREE_TYPE (b_use->decl) = b_use->u.type; } } + + /* Check if x is part of a FMV set with b_use. */ + if (b_use && TREE_CODE (b_use->decl) == FUNCTION_DECL + && TREE_CODE (x) == FUNCTION_DECL && DECL_FILE_SCOPE_P (b_use->decl) + && DECL_FILE_SCOPE_P (x) + && disjoint_version_decls (x, b_use->decl) + && comptypes (vistype, type) != 0) + { + maybe_mark_function_versioned (b_use->decl); + maybe_mark_function_versioned (b->decl); + maybe_mark_function_versioned (x); + + cgraph_node *b_node = cgraph_node::get_create (b_use->decl); + cgraph_function_version_info *b_v = b_node->function_version (); + if (!b_v) + b_v = b_node->insert_new_function_version (); + + /* Check if this new node conflicts with any previous functions + in the set. */ + cgraph_function_version_info *version = b_v; + for (; version; version = version->next) + if (!disjoint_version_decls (version->this_node->decl, x)) + { + /* The decls define overlapping version, so attempt to merge + or diagnose the conflict. */ + if (duplicate_decls (x, version->this_node->decl)) + return version->this_node->decl; + else + return error_mark_node; + } + + /* This is a new version to be added to FMV structure. */ + cgraph_node::add_function_version (b_v, x); + + /* Get the first node from the structure. */ + cgraph_function_version_info *default_v = b_v; + while (default_v->prev) + default_v = default_v->prev; + /* Always use the default node for the bindings. */ + b_use->decl = default_v->this_node->decl; + b->decl = default_v->this_node->decl; + + /* Node is not a duplicate, so no need to do the rest of the + checks. */ + return x; + } + if (duplicate_decls (x, b_use->decl)) { if (b_use != b) @@ -4496,6 +4576,12 @@ tree lookup_name (tree name) { struct c_binding *b = I_SYMBOL_BINDING (name); + /* Do not resolve non-default function versions. */ + if (b + && TREE_CODE (b->decl) == FUNCTION_DECL + && DECL_FUNCTION_VERSIONED (b->decl) + && !is_function_default_version (b->decl)) + return NULL_TREE; if (b && !b->invisible) { maybe_record_typedef_use (b->decl); @@ -5778,6 +5864,17 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, && VAR_OR_FUNCTION_DECL_P (decl)) objc_check_global_decl (decl); + /* To enable versions to be created across TU's we mark and mangle all + non-default versioned functions. */ + if (TREE_CODE (decl) == FUNCTION_DECL + && !TARGET_HAS_FMV_TARGET_ATTRIBUTE + && get_target_version (decl).is_valid ()) + { + maybe_mark_function_versioned (decl); + if (current_scope != file_scope) + error ("versioned declarations are only allowed at file scope"); + } + /* Add this decl to the current scope. TEM may equal DECL or it may be a previous decl of the same name. */ if (do_push) @@ -10754,6 +10851,17 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, warn_parm_array_mismatch (origloc, old_decl, parms); } + /* To enable versions to be created across TU's we mark and mangle all + non-default versioned functions. */ + if (TREE_CODE (decl1) == FUNCTION_DECL + && !TARGET_HAS_FMV_TARGET_ATTRIBUTE + && get_target_version (decl1).is_valid ()) + { + maybe_mark_function_versioned (decl1); + if (current_scope != file_scope) + error ("versioned definitions are only allowed at file scope"); + } + /* Record the decl so that the function name is defined. If we already have a decl for this name, and it is a FUNCTION_DECL, use the old decl. */ @@ -13585,6 +13693,10 @@ c_parse_final_cleanups (void) c_write_global_declarations_1 (BLOCK_VARS (DECL_INITIAL (t))); c_write_global_declarations_1 (BLOCK_VARS (ext_block)); + /* Call this to set cpp_implicit_aliases_done on all nodes. This is + important for function multiversioning aliases to get resolved. */ + symtab->process_same_body_aliases (); + if (!in_lto_p) free_attr_access_data (); diff --git a/gcc/testsuite/gcc.target/aarch64/mv-1.c b/gcc/testsuite/gcc.target/aarch64/mv-1.c new file mode 100644 index 00000000000..6f095ecd7a7 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-1.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_version ("default"))) int +foo () +{ + return 1; +} + +__attribute__ ((target_version ("rng"))) int +foo () +{ + return 2; +} + +__attribute__ ((target_version ("flagm"))) int +foo () +{ + return 3; +} + +__attribute__ ((target_version ("rng+flagm"))) int +foo () +{ + return 4; +} + +int +bar () +{ + return foo (); +} + +/* Check usage of the first two FMV features, in case of off-by-one errors. */ +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mrng:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._MrngMflagm:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mflagm:\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tbl\tfoo\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-and-mvc1.c b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc1.c new file mode 100644 index 00000000000..39ed306eec2 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc1.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +__attribute__((target_version("default"))) +int foo () +{ + return 0; +} + +__attribute__((target_clones("dotprod", "sve+sve2"))) +int foo () +{ + return 1; +} + +__attribute__((target_clones("sve", "sve2"))) +int foo () +{ + return 2; +} + +int bar() +{ + return foo (); +} + + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._MsveMsve2:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Msve:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Msve2:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tbl\tfoo\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-and-mvc2.c b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc2.c new file mode 100644 index 00000000000..17c7cbdd02d --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc2.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +__attribute__((target_version("default"))) +int foo (); + +__attribute__((target_clones("dotprod", "sve+sve2"))) +int foo () +{ + return 1; +} + +__attribute__((target_clones("sve", "sve2"))) +int foo () +{ + return 2; +} + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\nfoo:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._MsveMsve2:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Msve:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Msve2:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 0 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-and-mvc3.c b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc3.c new file mode 100644 index 00000000000..8325c8e0699 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc3.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +__attribute__((target_clones("dotprod", "sve+sve2"))) +int foo (); + +__attribute__((target_version("default"))) +int foo () +{ + return 0; +} + +__attribute__((target_clones("sve", "sve2"))) +int foo () +{ + return 2; +} + +int bar() +{ + return foo (); +} + + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._MsveMsve2:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Msve:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Msve2:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tbl\tfoo\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 1 } } */ +// { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, foo\.default\n" 1 } } +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, foo\._Mdotprod\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, foo\._MsveMsve2\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, foo\._Msve\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, foo\._Msve2\n" 1 } } */ + diff --git a/gcc/testsuite/gcc.target/aarch64/mv-and-mvc4.c b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc4.c new file mode 100644 index 00000000000..951c9500d74 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc4.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +__attribute__((target_version("dotprod"))) +int foo () +{ + return 0; +} + +__attribute__((target_clones("default", "sve+sve2"))) +int foo () +{ + return 1; +} + +__attribute__((target_clones("sve", "sve2"))) +int foo () +{ + return 2; +} + +int bar() +{ + return foo (); +} + + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._MsveMsve2:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Msve:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Msve2:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tbl\tfoo\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols1.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols1.c new file mode 100644 index 00000000000..798227826e5 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols1.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +// Basic case of fmv correctness with all functions and use in one TU. + +__attribute__ ((target_version ("default"))) int +foo () +{ + return 1; +} + +__attribute__ ((target_version ("dotprod"))) int +foo () +{ + return 3; +} +__attribute__ ((target_version ("sve+sve2"))) int +foo () +{ + return 5; +} + +int +bar () +{ + return foo (); +} + +/* When updating any of the symbol names in these tests, make sure to also + update any tests for their absence in mv-symbolsN.C */ + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._MsveMsve2:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tbl\tfoo\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols10.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols10.c new file mode 100644 index 00000000000..d5256389d7b --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols10.c @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +int +foo (); + +int +foo () +{ + return 1; +} + +__attribute__ ((target_version ("dotprod"))) int +foo () +{ + return 3; +} +__attribute__ ((target_version ("sve+sve2"))) int +foo () +{ + return 5; +} + +int +bar () +{ + return foo (); +} + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._MsveMsve2:\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx., foo\._MsveMsve2\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx., foo\._Mdotprod\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx., foo\.default\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\n\tbl\tfoo\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols11.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols11.c new file mode 100644 index 00000000000..fd3dc345a59 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols11.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +// Check that types can be combined + +__attribute__ ((target_version ("default"))) int +foo (int a, int (*b)[4]) { return 1; } + +__attribute__ ((target_version ("dotprod"))) int +foo (int a, int (*b)[]) { return 3; } + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols12.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols12.c new file mode 100644 index 00000000000..1a0b667eb5f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols12.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_version ("default"))) int +foo () { return 1; } + +__attribute__ ((target_version ("dotprod"))) int +foo () { return 3; } + +int bar () +{ + int (*test)() = foo; + + test(); +} + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\], foo\._Mdotprod\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\], foo\.default\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, foo\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols13.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols13.c new file mode 100644 index 00000000000..308dace64a7 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols13.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_version ("default"))) int +foo (); + +int bar () +{ + int (*test)() = foo; + + test(); +} + +__attribute__ ((target_version ("dotprod"))) int +foo () { return 3; } + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\], foo\._Mdotprod\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\], foo\.default\n" 0 } } */ + +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, foo\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 0 } } */ + diff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols14.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols14.c new file mode 100644 index 00000000000..d1af69fe31d --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols14.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +int foo (); + +__attribute__ ((target_version ("default"))) int +foo () +{ + return 1; +} + +__attribute__ ((target_version ("dotprod"))) int +foo () +{ + return 3; +} + +int +bar () +{ + return foo (); +} + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx., foo\._Mdotprod\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx., foo\.default\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\n\tbl\tfoo\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols2.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols2.c new file mode 100644 index 00000000000..a8732caf214 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols2.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +// FMV correctness with definitions but no call + +__attribute__ ((target_version ("default"))) int +foo () +{ + return 1; +} + +__attribute__ ((target_version ("dotprod"))) int +foo () +{ + return 3; +} +__attribute__ ((target_version ("sve+sve2"))) int +foo () +{ + return 5; +} + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._MsveMsve2:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols3.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols3.c new file mode 100644 index 00000000000..962bae93577 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols3.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +// FMV correctness with declarations but no implementation + +__attribute__ ((target_version ("default"))) int +foo (); + +__attribute__ ((target_version ("dotprod"))) int +foo (); + +__attribute__ ((target_version ("sve+sve2"))) int +foo (); + +int +bar () +{ + return foo (); +} + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._MsveMsve2:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\tbl\tfoo\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 0 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols4.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols4.c new file mode 100644 index 00000000000..a476800b2c5 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols4.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +// FMV correctness with a default implementation and declarations of other +// versions + +__attribute__ ((target_version ("default"))) int +foo () +{ + return 1; +} + +__attribute__ ((target_version ("dotprod"))) int +foo (); + +__attribute__ ((target_version ("sve+sve2"))) int +foo (); + +int +bar () +{ + return foo (); +} + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._MsveMsve2:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tbl\tfoo\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols5.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols5.c new file mode 100644 index 00000000000..4df20009f79 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols5.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +// FMV correctness with default declaration, and implementations of other +// versions. + +__attribute__ ((target_version ("default"))) int +foo (); + +__attribute__ ((target_version ("dotprod"))) int +foo () +{ + return 3; +} +__attribute__ ((target_version ("sve+sve2"))) int +foo () +{ + return 5; +} + +int +bar () +{ + return foo (); +} + +/* When updating any of the symbol names in these tests, make sure to also + update any tests for their absence in mvc-symbolsN.C */ + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._MsveMsve2:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\tbl\tfoo\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 0 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols6.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols6.c new file mode 100644 index 00000000000..cbf8bcaf8e1 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols6.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_version ("default"))) int +foo () +{ + return 1; +} + +int bar() +{ + return foo(); +} + +/* { dg-final { scan-assembler-times "\nfoo:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 0 } } */ +/* { dg-final { scan-assembler-times "bl\tfoo.default\n" 1 } } */ +/* { dg-final { scan-assembler-times ".global\tfoo\n" 1 } } */ +/* { dg-final { scan-assembler-times ".set\tfoo,foo.default\n" 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols7.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols7.c new file mode 100644 index 00000000000..2ea4d2ebf0f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols7.c @@ -0,0 +1,47 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_version ("dotprod"))) int +foo (); + +__attribute__ ((target_version ("sve+sve2"))) int +foo (); + +__attribute__ ((target_version ("default"))) int +foo (); + +int +bar () +{ + return foo (); +} + +__attribute__ ((target_version ("sve+sve2"))) int +foo () +{ + return 5; +} +__attribute__ ((target_version ("dotprod"))) int +foo () +{ + return 3; +} +__attribute__ ((target_version ("default"))) int +foo () +{ + return 1; +} + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._MsveMsve2:\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx., foo\._MsveMsve2\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx., foo\._Mdotprod\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx., foo\.default\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\n\tbl\tfoo\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols8.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols8.c new file mode 100644 index 00000000000..3e3eaf21aa9 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols8.c @@ -0,0 +1,47 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_version ("dotprod"))) int +foo (); + +__attribute__ ((target_version ("sve+sve2"))) int +foo (); + +__attribute__ ((target_version ("default"))) int +foo (); + +__attribute__ ((target_version ("sve+sve2"))) int +foo () +{ + return 5; +} +__attribute__ ((target_version ("dotprod"))) int +foo () +{ + return 3; +} +__attribute__ ((target_version ("default"))) int +foo () +{ + return 1; +} + +int +bar () +{ + return foo (); +} + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._MsveMsve2:\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx., foo\._MsveMsve2\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx., foo\._Mdotprod\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx., foo\.default\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\n\tbl\tfoo\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-symbols9.c b/gcc/testsuite/gcc.target/aarch64/mv-symbols9.c new file mode 100644 index 00000000000..8e0864f1663 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-symbols9.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_version ("dotprod"))) int +foo (); +__attribute__ ((target_version ("sve+sve2"))) int +foo (); + +int +foo () +{ + return 1; +} + +__attribute__ ((target_version ("dotprod"))) int +foo () +{ + return 3; +} +__attribute__ ((target_version ("sve+sve2"))) int +foo () +{ + return 5; +} + +int +bar () +{ + return foo (); +} + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._MsveMsve2:\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx., foo\._MsveMsve2\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx., foo\._Mdotprod\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tadrp\tx., foo\.default\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\n\tbl\tfoo\n" 1 } } */ + +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mvc-symbols1.c b/gcc/testsuite/gcc.target/aarch64/mvc-symbols1.c new file mode 100644 index 00000000000..3ad15e5bb73 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mvc-symbols1.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_clones ("default", "dotprod", "sve+sve2"))) int +foo () +{ + return 1; +} + +int +bar () +{ + return foo (); +} + +/* When updating any of the symbol names in these tests, make sure to also + update any tests for their absence in mvc-symbolsN.C */ + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._MsveMsve2:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\tbl\tfoo\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mvc-symbols2.c b/gcc/testsuite/gcc.target/aarch64/mvc-symbols2.c new file mode 100644 index 00000000000..78385ed904b --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mvc-symbols2.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_clones ("default", "dotprod", "sve+sve2"))) int +foo () +{ + return 1; +} + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._MsveMsve2:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mvc-symbols3.c b/gcc/testsuite/gcc.target/aarch64/mvc-symbols3.c new file mode 100644 index 00000000000..1cbe3fd0850 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mvc-symbols3.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_clones ("default", "dotprod", "sve+sve2"))) int +foo (); + +int +bar () +{ + return foo (); +} + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._MsveMsve2:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\tbl\tfoo\n" 1 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 0 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mvc-symbols4.c b/gcc/testsuite/gcc.target/aarch64/mvc-symbols4.c new file mode 100644 index 00000000000..abaf60f91c3 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mvc-symbols4.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_clones ("default", "dotprod", "sve+sve2"))) int +foo (); + +/* { dg-final { scan-assembler-times "\nfoo\.default:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._Mdotprod:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\nfoo\._MsveMsve2:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\nfoo\.resolver:\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\t\.type\tfoo, %gnu_indirect_function\n" 0 } } */ +/* { dg-final { scan-assembler-times "\n\t\.set\tfoo,foo\.resolver\n" 0 } } */ From patchwork Wed Sep 17 12:44:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alfie Richards X-Patchwork-Id: 120425 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AB7293858429 for ; Wed, 17 Sep 2025 12:51:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AB7293858429 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=selector1 header.b=GJdFIKHu; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=selector1 header.b=GJdFIKHu X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from AS8PR04CU009.outbound.protection.outlook.com (mail-westeuropeazon11011001.outbound.protection.outlook.com [52.101.70.1]) by sourceware.org (Postfix) with ESMTPS id 03F433858429 for ; Wed, 17 Sep 2025 12:46:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 03F433858429 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 03F433858429 Authentication-Results: server2.sourceware.org; arc=pass smtp.remote-ip=52.101.70.1 ARC-Seal: i=3; a=rsa-sha256; d=sourceware.org; s=key; t=1758113189; cv=pass; b=cstYIyY7uxb9jMSY8iuT9o7zsLoB5/B97n+zP0sHhlHLSroY52JCAynDxazZoEFARragkii3wEJMH6sY2C9oce1Nr0fYf7+sjwylA2By0nGwUYEFJBI7N3m6vOhdl/VVciJlolJOsBQiNOD/BuEGMNNKrM8qx3QpAlcGih1dZ0U= ARC-Message-Signature: i=3; a=rsa-sha256; d=sourceware.org; s=key; t=1758113189; c=relaxed/simple; bh=ZtcxjBdTJ1aktzt/T5qvCt/FFjXxWs9XZ3rCWjWuLrg=; h=DKIM-Signature:DKIM-Signature:From:To:Subject:Date:Message-ID: MIME-Version; b=LT2b9t8zevshJVg5hy66wy5DCcnzSvM99/JyCuiBC24xOZ0rSK18pOLCPvegWL7S+bJ+l8AtLR72wVqpXZuizo5sQazcDeF/sE5uOSxznzkvUmuli7opZC5APJ0W4ZPeZWuBiuP8xrSALy7A/TVwCG4Uqqgj83wOqGuPxz1EtH4= ARC-Authentication-Results: i=3; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 03F433858429 ARC-Seal: i=2; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=pass; b=eBUOTv8+9UJ/X09YWlzUkYs9s9gmxRUkeS1fYVP6HyLt91j+4lrpw/kADzT5n1DJJ607GNomVysauWhD1FwRNNrDRvqih/0iEEQWehMcSgJ5hMhAKQPnGouiVYbhH/WgeVSa0lpuqixm2gbRW91wcwtoKB1PLXjxpW0zU8xv3eppr5QsqFe4mYAbkcitKamb6Uz3FrY7oBoNqDyep+dD4Xkq7hpflICBd54XdKTwXgzI6mGXMm2E1JX/ehSWtxrEQDvTapeWPO7KaDalAnRWwmtzAKzX5IukeinFTyr3PGBkIaSwD3NvR5J7CvlrcutYJF2u80/B2J1vNWdtp9+FIQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=UHFNEZUKi4oaMlSom4I3OsdCmmlCJM5mngQQNX6uXwA=; b=xv1s67p+1A6uByhA3yfcL7t5C5hQunRKmSH5yvLSBZBH5WwYjpgvlLC55KPJMW/68RFFNRasOLRKNZx6Sw5ulZhgBXafpihlp/7fEMIkUaFlRRbizIlFBJ1DhvvSnJArxxlWXVseAnN7MlLTZjCsZ3laXzG09qAIuk/yF0hbIPm/+ulZsi1cirzVHWr8ffDjW1Q4P+QsZITUzmkXW6mH3ib0SwiMuKor0c6M/usu3v6UwTPaRqZ6Ah+h/zhKLJvdknfaokTSB11eBJKOU88FYK7TYynpiiHkp1R9E2MQztEqL1HwVy0mhKx/RLSO+afFJn0AQuT9VRr2pBWVRRUGxg== ARC-Authentication-Results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 4.158.2.129) smtp.rcpttodomain=gcc.gnu.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=pass (signature was verified) header.d=arm.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dmarc=[1,1,header.from=arm.com]) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=arm.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=UHFNEZUKi4oaMlSom4I3OsdCmmlCJM5mngQQNX6uXwA=; b=GJdFIKHuUC9DqpUW1lb6sRx+OsIizHEABEWoUGKxJJLzVt7NrVIQAeqmynlWn+4EkQyzuWnM9e8KFlDkzHM3H+uOrw2cPu9QTHQyoaeVeSsxbzCjkRDRdI0OeNFx7hzqBNN8AVErD15Wtg5eoRpudiNB7Hj7Oae4z1G1C8/5wwc= Received: from AS4P192CA0017.EURP192.PROD.OUTLOOK.COM (2603:10a6:20b:5e1::12) by AS4PR08MB7479.eurprd08.prod.outlook.com (2603:10a6:20b:4e6::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9115.22; Wed, 17 Sep 2025 12:46:19 +0000 Received: from AMS1EPF00000044.eurprd04.prod.outlook.com (2603:10a6:20b:5e1:cafe::30) by AS4P192CA0017.outlook.office365.com (2603:10a6:20b:5e1::12) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.13 via Frontend Transport; Wed, 17 Sep 2025 12:46:18 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 4.158.2.129) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=arm.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 4.158.2.129 as permitted sender) receiver=protection.outlook.com; client-ip=4.158.2.129; helo=outbound-uk1.az.dlp.m.darktrace.com; pr=C Received: from outbound-uk1.az.dlp.m.darktrace.com (4.158.2.129) by AMS1EPF00000044.mail.protection.outlook.com (10.167.16.41) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.12 via Frontend Transport; Wed, 17 Sep 2025 12:46:18 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=lH5RQmTaJe53BYBXuIYQhkM6qiPGZ+YMsEXCH4ZkchZybZciivHRFFAu6zQrTWqSHoGLCytFGAttemSpWwroC/p+DuK69z0q+jc4bwEEtzUYTO4BDGnzrZm56cfuTJW3EvzZQMF/WCNq+GC6F33QOZxQQPQQumbmfLNh78uP2eiCPfXtJ2L7VpUPQKl4egweLpcdD7lqIgektuODb3+WCoE7qMmHt56PdNi8mt3JvM2ZlvF6Ti0bNin/1XcWKhEIfv5WA/M455hUBh3Ns9UeUvveUPhAxwZNDRr5u5sib8Zhg+ep1HLgwJbGNYZ+EE/wHJUMLFoHFLelI5Uizti6Mg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=UHFNEZUKi4oaMlSom4I3OsdCmmlCJM5mngQQNX6uXwA=; b=DRWeIeRG0U9XD+l9YDXtRJ4VctHwu4yaUFGIJT8v+OIlRtNmscBzDwd4K6v00fa23DqgCqjxrcgUybAKJltruET+w7JJkIdlFMm3w8oWmiG33++JhtHY4JhOpQ1NinysJ4PvdzLPJxTmlPC2u1HiS2hABQ0YrhfjDj97K+Qkass0DWPpIx6eS8IBHC0QoUV4AzbcFO3O9+KBHaceL8S96VDbedi3HMNgc8r3B2GAXYGLOf16aRRY/vBeMBYR3MOBoPfmlgYcCamh7pymPh1Do0MCwlCHZeQI7bPUFUtGJEOT9VptM0ll6ZFrHrGDqkmg17Entwa3arLkjFv4CbBOog== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 172.205.89.229) smtp.rcpttodomain=gcc.gnu.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=arm.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=UHFNEZUKi4oaMlSom4I3OsdCmmlCJM5mngQQNX6uXwA=; b=GJdFIKHuUC9DqpUW1lb6sRx+OsIizHEABEWoUGKxJJLzVt7NrVIQAeqmynlWn+4EkQyzuWnM9e8KFlDkzHM3H+uOrw2cPu9QTHQyoaeVeSsxbzCjkRDRdI0OeNFx7hzqBNN8AVErD15Wtg5eoRpudiNB7Hj7Oae4z1G1C8/5wwc= Received: from AM4PR07CA0007.eurprd07.prod.outlook.com (2603:10a6:205:1::20) by DU0PR08MB9656.eurprd08.prod.outlook.com (2603:10a6:10:446::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.13; Wed, 17 Sep 2025 12:45:45 +0000 Received: from AM3PEPF0000A796.eurprd04.prod.outlook.com (2603:10a6:205:1:cafe::7a) by AM4PR07CA0007.outlook.office365.com (2603:10a6:205:1::20) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9137.11 via Frontend Transport; Wed, 17 Sep 2025 12:45:48 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 172.205.89.229) smtp.mailfrom=arm.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 172.205.89.229 as permitted sender) receiver=protection.outlook.com; client-ip=172.205.89.229; helo=nebula.arm.com; pr=C Received: from nebula.arm.com (172.205.89.229) by AM3PEPF0000A796.mail.protection.outlook.com (10.167.16.101) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.9137.12 via Frontend Transport; Wed, 17 Sep 2025 12:45:45 +0000 Received: from AZ-NEU-EXJ01.Arm.com (10.240.25.132) by AZ-NEU-EX06.Arm.com (10.240.25.134) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Wed, 17 Sep 2025 12:44:58 +0000 Received: from AZ-NEU-EX05.Arm.com (10.240.25.133) by AZ-NEU-EXJ01.Arm.com (10.240.25.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Wed, 17 Sep 2025 12:44:58 +0000 Received: from ip-10-248-139-135.eu-west-1.compute.internal (10.248.139.135) by mail.arm.com (10.240.25.133) with Microsoft SMTP Server id 15.1.2507.39 via Frontend Transport; Wed, 17 Sep 2025 12:44:58 +0000 From: To: , CC: , , , , , , , , , , , , , Alfie Richards Subject: [PATCH v11 12/13] c: aarch64: Add FMV diagnostic tests. Date: Wed, 17 Sep 2025 12:44:56 +0000 Message-ID: <20250917124456.170437-5-alfie.richards@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250917124456.170437-1-alfie.richards@arm.com> References: <20250917124456.170437-1-alfie.richards@arm.com> MIME-Version: 1.0 X-EOPAttributedMessage: 1 X-MS-TrafficTypeDiagnostic: AM3PEPF0000A796:EE_|DU0PR08MB9656:EE_|AMS1EPF00000044:EE_|AS4PR08MB7479:EE_ X-MS-Office365-Filtering-Correlation-Id: 79d83198-224f-4709-8f98-08ddf5e83273 x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; ARA:13230040|7416014|376014|82310400026|36860700013|1800799024; X-Microsoft-Antispam-Message-Info-Original: zkWvU4DICydLzUQDyx5PIvFnK6gidU+2MlFYUlscHF1iOO/AiuIa9WHOmemHbeZMSa3TXxiMT2F6kd9Ry6WqUZmKUq3X2flPGB0bnWBX/IJYqom/la1cY+oIw0+L/wP0jlnFDedScQ71JRpHg6nJeemOS/DDypbZoSFH6wmBJ/gFMBZmXcRxVaoDafNU8alUSdAF76eGPH52VPZuXB8sqEcNz+4iniOmYMx3Dqr7Wy+nrpNRqDa7c20d2eI4vOIhOofxzF0hdrr6knwezSJk6Q/5b3pktfs3588nJxr980ZnLZbrKv1t9Sv/VLn3VVoXJS2DBnhoQWoZrKD7wC+HwU+ZhjiCjTHtvBINFkL1mLZOQsqotRJgY/PhYeS9q165IycfjHSUSwTRCKAjqDfVvZk1t1X6iGHl8NG3QXCeiZQ46ZC7bnuCFpsybGg4zdBWQv51ifMjc4b/Lt7i6xZ2MoNVhGXVv6zZs58i2Qz8e/x5GSVlIJFYhO68npNzUB6KpKY2i2lq27/qBsp6xHo7ekB1CAZ2DUdkuS0Yft1VVqUVwm/4TvOQ1LmuAW4TxSt9VG0HfMFC65DZcQjA+rVGojdgJlPTNebMogNQ7m6M5hjaI9xkvWUD5UTaGY+3IdgI5vwzNcFXA+LSs6lvdhKT0UgdGoVWpR3YO4XzGm1aeaDCOTYBopwVRTl8D/ANq2WivfL739cIQVzwzH1sYqH+sSxqqiRI+k7s1Laa9V4ObHkQa0oWkwoS41Rmg03PWYd2baSVdJNBBqgT3ntaUmvg9Wa5AZY6iqCHuVBGUuTL3lNIhXPuzoK6qf4v8nUthW1rEgp3l9SSkkd0x2P7WZdfrnltHQ1pdoNXU6pjW4VAmudgysVBk0KcPHbphcSQZ8PGyn7uINylY/sAygnYjt1/KuN12uPHAPJVCh6OdUbMV8IygvPTnHPQMQPjP+U8fBla6ZjcvR4P/QNfjhs1Uah5IXR5d72XnsM/mHK9fnPDqrydGCmSk1i6EvP4P9j8woNREc8IFIDpv0v9PQQ36Q6bu4zF8qX3pRMKIvMhg/cE2zhPUE+b3zYWOyjuieyYzIORWJ7O2IhpdQIGXFmQYhyu+XihZwTQN3MAFvES0Jx9TcU/8sLKusvmRd+eMAuG8oWcH6Of/420xG0Kui3WnsInRhCzlaOb2ocTOf2OLp/XatX/ld/7xgSXds6oFqWb03hcQ87tjqtgnUFOLbXVtYgN7EZ+UV3Xf/RfI7SLiZvcWegEdUigel5HzEehpRBit5pPZRtVnRz4iLBhk97BspUTIoZmz+bE3J36ftFz4MgQHyU/kWwNa0SuQXq1Rijfa3gDjG8Dv1J2hSGfV3uKekGsc3ifk/eoYinQDRINGbV3DDi8qnclmaxV2PgZ51QECnH8v1USJs2rQ0vdlMW0z7hCecVnDmZO1rF7CrQ+0WbN3T6+0DTzkFz5tcxN0TGZUXyiwNU5DvZAXNhFiPIvJpQyyg== X-Forefront-Antispam-Report-Untrusted: CIP:172.205.89.229; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:nebula.arm.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230040)(7416014)(376014)(82310400026)(36860700013)(1800799024); DIR:OUT; SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB9656 X-MS-Exchange-Transport-CrossTenantHeadersStripped: AMS1EPF00000044.eurprd04.prod.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: 73c590dd-0ee3-4f73-0b39-08ddf5e81ea7 X-Microsoft-Antispam: BCL:0; ARA:13230040|14060799003|7416014|376014|82310400026|35042699022|36860700013|1800799024; X-Microsoft-Antispam-Message-Info: euZvDqD4hhPfY560y6usIKjyKb6n7SnadNKKRdDqficHdYnLxFMMqt9cTa04o2Zn9WIcjXiDhqVS4n0dEhdaMnz4DL8FEEga4yQfduwekit5VFCcIXKbRKA/xvlBC2GDzrqfKLxa/yg0WKTEkRKemBufswDp+1gSd4PJjvr7fJqQ/4v5akXUkk5P35rwos8PbHTNaU1IYBXTz/TVGzp18cFTLvOSlet9tOgKAezlEiymhLnkugHVlNaoMzyfd90WnD9PW0vzeE735iF8IbRbXr9BPs5OLYEGBt3AkMEhSHCkzqXlbjQGB+jF2qcaqE0Hmc4THNMi2Rc2sK+OxW17IPiE8YltyovTFLCY06i2LbAKKL86GC6i3g3a+XEuK1r0MCFrKh316v42wroVfgINwoddkPkrMd3eBgQfcFvigNhPLxmSUSH2c1XzI3CCX0XKMNCi1lYHbHvezl42y745Ylg3IXFni2muVTqJ3graWZ6pOepQCts0qLg7uSQU3Q3MJDmG+MGjKFKImRPqzG8ffRAy9JadRtj7mUDcUWSp2L6yRPliCkE4iYwvbOGcEkvcySoEStr4r75IvdiJYlcP+62B7biuVldh1RAWarVliifrGKFzBts4awJqSv/aTBAjyZHElGukZuHNQCBmi/14eMi7TuAak5AkDVNgWsDIwYOS1Fo2ZAjCv7jDZXzonGoRW6Hm1YpvlzfnCguxuCCir188/nSC/8DsH88gWkoF9HjJPxdiDoD6qXL2Uw3UTjz4I7VkGpQQJu0HxLkOdtAQkaUWMJm2VysYZPfPa3BNsRY0YmXRGRNG6gFb6CCCgs98kl6b6k2mPz01Egphih9RTpkiZyVwMifglaL2lg+trQw930pfQrUtmwi7cyclLKD6U+iF4fLRkHZJUcI1v4d7FAk4rnUl+vkWGldhQsD2zQ5YqGzca5HxgN3aSFXebOQITyEYHkilf8ju1EJV1AfVSs2esHL5Uy7wO2MWilnGbaf9BO1DIdivaK8fQTu650BXoHXrjjJRZ/sAFTEKxL/ha4f10yOlxz+MYanvp5MyJgzTH5DQlWrLU+DvwFrSNiPM5vVF3rLUBUJGePhBU4dxmn+zeh3GfSfgC3k1JwmjRmsYi+Uo+fU+dqm8wx34EjxMTmo46qsYDEX86VuDrmOCdJVcikS2aRp692FJCz8rQewWkETs9PQK/99hMYPvXrtsV2UBQ+hWz+wwSE9j4KHdQsi3IkuaswsaWX+6TGiQ+Lz4L2WQpJ23OERDkzkYngjXj2bpKXb7RPyRSa6oiDGgktrzFLBy4zXpF6dRwVD33yzC7YxUuRjS2huOnRJEgnqi4EHSZCA56iSBHbDaPZuAaIxCiC8BTNX+dfeHWm0E390kSdB2trhlVwz3UDTWOPYWqLRwylInEHjd/porkDR1YIvuVKfHZ3V+vgbbcoxx++ApcaPq5JaQion4Wqz++V1qF5uvg4Buh0LgR3KazBVS5g== X-Forefront-Antispam-Report: CIP:4.158.2.129; CTRY:GB; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:outbound-uk1.az.dlp.m.darktrace.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230040)(14060799003)(7416014)(376014)(82310400026)(35042699022)(36860700013)(1800799024); DIR:OUT; SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Sep 2025 12:46:18.3078 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 79d83198-224f-4709-8f98-08ddf5e83273 X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[4.158.2.129]; Helo=[outbound-uk1.az.dlp.m.darktrace.com] X-MS-Exchange-CrossTenant-AuthSource: AMS1EPF00000044.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS4PR08MB7479 X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FORGED_SPF_HELO, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_PASS, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org From: Alfie Richards Adds some aarch64 C fmv diagnostic tests. This mostly tests C front end code, but has to be target specific at FMV is requires specifying target extensions. gcc/testsuite/ChangeLog: * gcc.target/aarch64/mv-and-mvc-error1.c: New test. * gcc.target/aarch64/mv-and-mvc-error2.c: New test. * gcc.target/aarch64/mv-and-mvc-error3.c: New test. * gcc.target/aarch64/mv-error1.c: New test. * gcc.target/aarch64/mv-error2.c: New test. * gcc.target/aarch64/mv-error3.c: New test. * gcc.target/aarch64/mv-error4.c: New test. * gcc.target/aarch64/mv-error5.c: New test. * gcc.target/aarch64/mv-error6.c: New test. * gcc.target/aarch64/mv-error7.c: New test. * gcc.target/aarch64/mv-error8.c: New test. * gcc.target/aarch64/mv-error9.c: New test. * gcc.target/aarch64/mv-error10.c: New test. * gcc.target/aarch64/mvc-error1.c: New test. * gcc.target/aarch64/mvc-error2.c: New test. * gcc.target/aarch64/mvc-warning1.c: New test. --- .../gcc.target/aarch64/mv-and-mvc-error1.c | 9 +++++++++ .../gcc.target/aarch64/mv-and-mvc-error2.c | 9 +++++++++ .../gcc.target/aarch64/mv-and-mvc-error3.c | 8 ++++++++ gcc/testsuite/gcc.target/aarch64/mv-error1.c | 18 +++++++++++++++++ gcc/testsuite/gcc.target/aarch64/mv-error10.c | 13 ++++++++++++ gcc/testsuite/gcc.target/aarch64/mv-error2.c | 9 +++++++++ gcc/testsuite/gcc.target/aarch64/mv-error3.c | 12 +++++++++++ gcc/testsuite/gcc.target/aarch64/mv-error4.c | 9 +++++++++ gcc/testsuite/gcc.target/aarch64/mv-error5.c | 8 ++++++++ gcc/testsuite/gcc.target/aarch64/mv-error6.c | 20 +++++++++++++++++++ gcc/testsuite/gcc.target/aarch64/mv-error7.c | 11 ++++++++++ gcc/testsuite/gcc.target/aarch64/mv-error8.c | 12 +++++++++++ gcc/testsuite/gcc.target/aarch64/mv-error9.c | 12 +++++++++++ gcc/testsuite/gcc.target/aarch64/mvc-error1.c | 9 +++++++++ gcc/testsuite/gcc.target/aarch64/mvc-error2.c | 9 +++++++++ .../gcc.target/aarch64/mvc-warning1.c | 13 ++++++++++++ 16 files changed, 181 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-and-mvc-error1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-and-mvc-error2.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-and-mvc-error3.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-error1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-error10.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-error2.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-error3.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-error4.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-error5.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-error6.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-error7.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-error8.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mv-error9.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mvc-error1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mvc-error2.c create mode 100644 gcc/testsuite/gcc.target/aarch64/mvc-warning1.c diff --git a/gcc/testsuite/gcc.target/aarch64/mv-and-mvc-error1.c b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc-error1.c new file mode 100644 index 00000000000..b08de29dd3c --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc-error1.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_version ("dotprod"))) int +foo () { return 3; } /* { dg-message "previous definition of .foo \\\[\\\[target_version\\(.dotprod.\\)\\\]\\\]. with type .int\\(void\\)." } */ + +__attribute__ ((target_clones ("dotprod", "sve"))) int +foo () { return 1; } /* { dg-error "redefinition of .foo \\\[\\\[target_clones\\(.dotprod., .sve.\\)\\\]\\\]." } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-and-mvc-error2.c b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc-error2.c new file mode 100644 index 00000000000..d34b246efc5 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc-error2.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_version ("default"))) int +foo () { return 1; } /* { dg-message "previous definition of .foo \\\[\\\[target_version\\(.default.\\)\\\]\\\]. with type .int\\(void\\)." } */ + +__attribute__ ((target_clones ("dotprod", "sve"))) float +foo () { return 3; } /* { dg-error "conflicting types for .foo \\\[\\\[target_clones\\(.dotprod., .sve.\\)\\\]\\\].; have .float\\(void\\)." } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-and-mvc-error3.c b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc-error3.c new file mode 100644 index 00000000000..a6a45bdf7aa --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-and-mvc-error3.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +float foo () { return 1; } /* { dg-message "previous definition of .foo." } */ + +__attribute__ ((target_clones ("default", "dotprod", "sve"))) float +foo () { return 3; } /* { dg-error "redefinition of .foo \\\[\\\[target_clones\\(.default., .dotprod., .sve.\\)\\\]\\\]." } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-error1.c b/gcc/testsuite/gcc.target/aarch64/mv-error1.c new file mode 100644 index 00000000000..61c9af276e6 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-error1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_version ("default"))) int +foo (); + +__attribute__ ((target_version ("default"))) int +foo () { return 1; } /* { dg-message "previous definition of .foo \\\[\\\[target_version\\(.default.\\)\\\]\\\]. with type .int\\(void\\)." } */ + +__attribute__ ((target_version ("dotprod"))) float +foo () { return 3; } /* { dg-error "conflicting types for .foo \\\[\\\[target_version\\(.dotprod.\\)\\\]\\\].; have .float\\(void\\)." } */ + +__attribute__ ((target_version ("sve"))) int +foo2 () { return 1; } /* { dg-message "previous definition of .foo2 \\\[\\\[target_version\\(.sve.\\)\\\]\\\]. with type .int\\(void\\)." } */ + +__attribute__ ((target_version ("dotprod"))) float +foo2 () { return 3; } /* { dg-error "conflicting types for .foo2 \\\[\\\[target_version\\(.dotprod.\\)\\\]\\\].; have .float\\(void\\)." } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-error10.c b/gcc/testsuite/gcc.target/aarch64/mv-error10.c new file mode 100644 index 00000000000..218f103a8f4 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-error10.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +void +bar () +{ + __attribute__ ((target_version ("dotprod"))) int + foo1 (); /* { dg-message "versioned declarations are only allowed at file scope" } */ + + __attribute__ ((target_version ("simd"))) int + foo2 () { return 1; } /* { dg-message "versioned definitions are only allowed at file scope" } */ +} diff --git a/gcc/testsuite/gcc.target/aarch64/mv-error2.c b/gcc/testsuite/gcc.target/aarch64/mv-error2.c new file mode 100644 index 00000000000..19d961d0a5a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-error2.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_version ("dotprod"))) float +foo () { return 3; } /* { dg-message "previous definition of .foo \\\[\\\[target_version\\(.dotprod.\\)\\\]\\\]. with type .float\\(void\\)." } */ + +__attribute__ ((target_version ("dotprod"))) float +foo () { return 3; } /* { dg-error "redefinition of .foo \\\[\\\[target_version\\(.dotprod.\\)\\\]\\\]." } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-error3.c b/gcc/testsuite/gcc.target/aarch64/mv-error3.c new file mode 100644 index 00000000000..451ce028c65 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-error3.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_version ("dotprod"))) float +foo () { return 3; } + +__attribute__ ((target_version ("default"))) float +foo () { return 3; } /* { dg-message "previous definition of .foo \\\[\\\[target_version\\(.default.\\)\\\]\\\]. with type .float\\(void\\)." } */ + +__attribute__ ((target_version ("default"))) float +foo () { return 3; } /* { dg-error "redefinition of .foo \\\[\\\[target_version\\(.default.\\)\\\]\\\]." } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-error4.c b/gcc/testsuite/gcc.target/aarch64/mv-error4.c new file mode 100644 index 00000000000..44d3195590d --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-error4.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_version ("test"))) float +foo () { return 3; } /* { dg-error "invalid feature modifier .test. of value .test. in .target_version. attribute" } */ + +__attribute__ ((target_version ("sve+test"))) float +foo2 () { return 3; } /* { dg-error "invalid feature modifier .test. of value .sve.test. in .target_version. attribute" } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-error5.c b/gcc/testsuite/gcc.target/aarch64/mv-error5.c new file mode 100644 index 00000000000..776b80a45b6 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-error5.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_version ("sve+sve2"))) int +foo(); /* { dg-message "previous declaration of .foo \\\[\\\[target_version\\(.sve\\\+sve2.\\)\\\]\\\]. with type .int\\(void\\)." } */ + +int bar () { return foo (); } /* { dg-error "implicit declaration of function .foo." } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-error6.c b/gcc/testsuite/gcc.target/aarch64/mv-error6.c new file mode 100644 index 00000000000..afc71a44e73 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-error6.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_version ("sve+sve2"))) int +foo () { + return 1; +} + +__attribute__ ((target_version ("sve"))) int +foo () { /* { dg-message "previous definition of .foo \\\[\\\[target_version\\(.sve.\\)\\\]\\\]. with type .int\\(void\\)." } */ + return 1; +} + +int bar () { return foo (); } /* { dg-error "implicit declaration of function .foo." } */ + +__attribute__ ((target_version ("sve+sve2"))) int +foo2(); /* { dg-message "previous declaration of .foo2 \\\[\\\[target_version\\(.sve\\\+sve2.\\)\\\]\\\]. with type .int\\(void\\)." } */ + +int bar2 () { return foo2 (); } /* { dg-error "implicit declaration of function .foo2." } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-error7.c b/gcc/testsuite/gcc.target/aarch64/mv-error7.c new file mode 100644 index 00000000000..68db9783ce6 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-error7.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_version ("dotprod"))) int +foo (); /* { dg-message "previous declaration of .foo \\\[\\\[target_version\\(.dotprod.\\)\\\]\\\]. with type .int\\(void\\)." } */ + +__attribute__ ((target_version ("sve+sve2"))) int +foo (); + +int bar () { return foo (); } /* { dg-error "implicit declaration of function .foo." } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mv-error8.c b/gcc/testsuite/gcc.target/aarch64/mv-error8.c new file mode 100644 index 00000000000..7599df189e4 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-error8.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_version ("default"))) int +foo (int a, int (*b)[4]) { return 1; } + +int bar(void) { + __attribute__ ((target_version ("dotprod"))) int + foo (int a, int (*b)[5]) { return 3; } /* { dg-error "versioned definitions are only allowed at file scope" } */ + + return 1; +} diff --git a/gcc/testsuite/gcc.target/aarch64/mv-error9.c b/gcc/testsuite/gcc.target/aarch64/mv-error9.c new file mode 100644 index 00000000000..dc982e9d415 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mv-error9.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_version ("dotprod"))) int +foo (); /* { dg-message "previous declaration of .foo \\\[\\\[target_version\\(.dotprod.\\)\\\]\\\]. with type .int\\(void\\)." } */ + +int +bar () +{ + return foo (); /* { dg-error "implicit declaration of function .foo." } */ +} diff --git a/gcc/testsuite/gcc.target/aarch64/mvc-error1.c b/gcc/testsuite/gcc.target/aarch64/mvc-error1.c new file mode 100644 index 00000000000..482d0a71e67 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mvc-error1.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_clones ("default, dotprod"))) float +foo (); /* { dg-message "previous declaration of .foo \\\[\\\[target_clones\\(.default., .dotprod.\\)\\\]\\\]." } */ + +__attribute__ ((target_clones ("dotprod", "sve"))) float +foo () { return 3; } /* { dg-error ".foo \\\[\\\[target_clones\\(.dotprod., .sve.\\)\\\]\\\]. conflicts with overlapping .target_clone. declaration" } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mvc-error2.c b/gcc/testsuite/gcc.target/aarch64/mvc-error2.c new file mode 100644 index 00000000000..482d0a71e67 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mvc-error2.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +__attribute__ ((target_clones ("default, dotprod"))) float +foo (); /* { dg-message "previous declaration of .foo \\\[\\\[target_clones\\(.default., .dotprod.\\)\\\]\\\]." } */ + +__attribute__ ((target_clones ("dotprod", "sve"))) float +foo () { return 3; } /* { dg-error ".foo \\\[\\\[target_clones\\(.dotprod., .sve.\\)\\\]\\\]. conflicts with overlapping .target_clone. declaration" } */ diff --git a/gcc/testsuite/gcc.target/aarch64/mvc-warning1.c b/gcc/testsuite/gcc.target/aarch64/mvc-warning1.c new file mode 100644 index 00000000000..1bae38cceeb --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mvc-warning1.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0" } */ + +__attribute__((target_clones("default", "dotprod", "sve+sve2"))) +int foo () { + return 1; +} + +__attribute__((target_clones("invalid1"))) +int foo () { /* { dg-warning "invalid feature modifier .invalid1. in version .invalid1. for .target_clones. attribute" } */ + return 2; +}