[07/13] match-sat-alu.pd: Recognize X + MIN (~X, Y) as unsigned saturating addition
| Message ID | 20260902145254.77832-9-ktkachov@nvidia.com |
|---|---|
| State | New |
| Headers |
Return-Path: <gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org> X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C489E4BAE7D4 for <patchwork@sourceware.org>; Wed, 2 Sep 2026 14:58:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C489E4BAE7D4 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=Nvidia.com header.i=@Nvidia.com header.a=rsa-sha256 header.s=selector2 header.b=QaadAsES X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from DM1PR04CU001.outbound.protection.outlook.com (mail-centralusazon11010051.outbound.protection.outlook.com [52.101.61.51]) by sourceware.org (Postfix) with ESMTPS id 326DC4B9DB5B for <gcc-patches@gcc.gnu.org>; Wed, 2 Sep 2026 14:53:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 326DC4B9DB5B Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=nvidia.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 326DC4B9DB5B Authentication-Results: sourceware.org; arc=pass smtp.remote-ip=52.101.61.51 ARC-Seal: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1788360828; cv=pass; b=lHyPbCHQLw/owp+Z/ecijM1dxhvk3/0oCExCx6dBaspq595xFCYOgaV29ph3arNzwc38sl2biazO0z9Bjw2oT0P7+4o5oLm2PwYG2Hjs+FDjAF8xrufg8W5TJFPtB2/N4HJWDmtGh8x/yjwa4qemNm9MytUvSgs9wa38ke8IjuA= ARC-Message-Signature: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1788360828; c=relaxed/simple; bh=GB2OG777EgOtX6zmatDc4GnhE23pu6aCnvw1YzufEgg=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=SyFSL8CnMKX73Tx56+iEagQbsCUlyFaabyUe1F0Hybhl2hlOiRV//lUITRyIc/H0efM2k2BWwhsk1KF78K27CKXNH5xkQdVv4k6oEXRnHAZDzy6XkmNo/93B0/F61PEi/YZwDecspPe1dxf8EeU0g2VdktKLBgw+QWrDj/V/Tc8= ARC-Authentication-Results: i=2; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=Nvidia.com header.i=@Nvidia.com header.a=rsa-sha256 header.s=selector2 header.b=QaadAsES DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 326DC4B9DB5B ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=NF1eqEoMl7vvayFk9PE3768S6hI8pyZh9QhEQw7RI5yh+omFw9LnitZFld50Fot7bQjgZwa/9PbMcfdIB4SPascJirc7qWBDKY0/OmPU6fcQYryTAq+8ZJq3HUgeaCoFr82JU8mRe9v6b77gAwWwgJO1E1PZuI9kf87IpcVo5A8/2ngWgKvKlxLAYkwOjTdY+Dt62M6CWSNubKvjc/bFkbxDJtlnVrT8aYyuPJ/e59h0jR6p7COBnYA9d/pXUsSmQ+TkMNCZ28N48imt3HGAqfzjQMd6aO21uuJTe9FYh4BFxX9SMyGThyFAZaA9sRhPgB/WQQT1CUWjzBxt6VGRDA== 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=Hj3Y6mkDQ4jLOpHPG+SxObnDJ4zS8a8nNrX5dR0peeo=; b=O9ZZb5hP+uNWANLU8Qjl4bKhZxDxuOtdrPP45QtJZn7t30xior3Ccukm8Nvep+WP5kcNBKFlywiWRnSkS6S36tRcYeptvfhmfuRVOwT04xrhZjbtT/IYCHEa14qMba6QNymGCwGCYel/y87fj0zv6DQR3NPdzCrc5WeH2KFMUOAPHGlJclcA6XoVHIMyEnVktP5+0F+sQL0D7rRxjexqyplL0GM4hR7wkgdJsIpmX9d2zzc5TlxbFE4HRCvE6OqumJA1gXes74uA586EtemN1G/TNNh8BotapaiGn11zjSOtsqnr0ktkD0qy8E/fgnhT2wuPkMnGd8NZaq2k0G1NDQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.117.161) smtp.rcpttodomain=gcc.gnu.org smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Hj3Y6mkDQ4jLOpHPG+SxObnDJ4zS8a8nNrX5dR0peeo=; b=QaadAsESnlx1yb19aSfyb25qsfwcVYwJSXebs9yM8oJ30S2qqAoYdINcytoUlm4OR34C3A8bVzylvW7ei0Qh00snnPYs3iy2tZGECnNjNg5Nja84QoeuQFU0EH3bzz0k+ngz0EbpkNPfJzt92TNQTwgE95/PqkBebNmYOLyEzcMCcwL8JXIQegqNp0KGGwCKvjYvdlC22jLfwyBP1VOtYeDC5fILWVT2ELQbeZYV6g39KDlUm5LmTwCNHcusWj3pMrXlW7VOXr+vnuPmIY1unxTNEIVo5K62DsTWgdFrBIi6RnVUoyvo8/c6Y1DoLOq63MszBalqQTu2pFH/0D85TA== Received: from SA9PR03CA0029.namprd03.prod.outlook.com (2603:10b6:806:20::34) by SN7PR12MB7978.namprd12.prod.outlook.com (2603:10b6:806:34b::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.13; Wed, 2 Sep 2026 14:53:44 +0000 Received: from SA2PEPF00001509.namprd04.prod.outlook.com (2603:10b6:806:20:cafe::96) by SA9PR03CA0029.outlook.office365.com (2603:10b6:806:20::34) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.382.11 via Frontend Transport; Wed, 2 Sep 2026 14:53:43 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.117.161) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.117.161 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.117.161; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.117.161) by SA2PEPF00001509.mail.protection.outlook.com (10.167.242.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.382.8 via Frontend Transport; Wed, 2 Sep 2026 14:53:43 +0000 Received: from rnnvmail201.nvidia.com (10.129.68.8) by mail.nvidia.com (10.129.200.67) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.46; Wed, 2 Sep 2026 07:53:15 -0700 Received: from ktkachov-mlt.nvidia.com (10.126.230.37) by rnnvmail201.nvidia.com (10.129.68.8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.46; Wed, 2 Sep 2026 07:53:14 -0700 From: <ktkachov@nvidia.com> To: <gcc-patches@gcc.gnu.org> CC: Kyrylo Tkachov <ktkachov@nvidia.com> Subject: [PATCH 07/13] match-sat-alu.pd: Recognize X + MIN (~X, Y) as unsigned saturating addition Date: Wed, 2 Sep 2026 16:52:48 +0200 Message-ID: <20260902145254.77832-9-ktkachov@nvidia.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260902145254.77832-1-ktkachov@nvidia.com> References: <20260902145254.77832-1-ktkachov@nvidia.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [10.126.230.37] X-ClientProxiedBy: rnnvmail202.nvidia.com (10.129.68.7) To rnnvmail201.nvidia.com (10.129.68.8) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SA2PEPF00001509:EE_|SN7PR12MB7978:EE_ X-MS-Office365-Filtering-Correlation-Id: a5cbe1b4-5315-426b-aafd-08df0901fc21 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|82310400026|36860700016|1800799024|23010399003|376014|18002099003|22082099003|56012099006|3023799007|10067099003|6133799003|11063799006; X-Microsoft-Antispam-Message-Info: iGJMdpq7zf0Fu0UrWvVLzbhvEweAqA98ATuyerkBfiDrkFvZQWwSn2dqG/rVxheKrJMeakqW7X0dAZy1Ukj9Gbn5vJwkbe0u5haQDcewmkBQIZgRrWCCL7LdulLMHyN3iXf6xtvVahJugx8FiLfVL97Jz71yunmBB3A3RVIdJBmcouefDXVTytmqHkjCyQUncDSFrHjeVBNDnzqGqZOes+zfd5nWCR1L2XrXuPpPuH/SjNexFvvG+t0HDrT00seKwC1fFJ5aPAMpqJNiOTqBdAxUFd8z7DhYI4DfQqNEOwyWS51b/qwkpVMvE7/RB+CPaYohUtTzNtyWzZAvcwmFE1w3na+JK8cxBeF0oVYEyXPXceE4scT9kL2KN1C2r3baN8JqC3hPJqL483fYmQn9z79MAr1M9Lo+ZJ5Z9MrGmWBHrh0g+TQBjtDKpGb7Jg1pcBhUb2JxY8cpzG2DILsBecPVoM+so8NT4iFl6s11a6V+mDROVukbW2p+l+pr4h/k4iqslRks/uSOY+OTq/UJFCLqLgSKYX2Ot29Z/ar8M5g1MP1a8HO0On7XlTTNEcEOdBIFW0E+YZAFPulc9WTmzDaZ+lLgoxjOKQBuCjkCu0efN/xaiE6dkkCQKRtkvG8h2lPUJ7d3lXtJHTsFxAa6ZWPiUz9NRSMjYegUZcLc9ONvA/3M+ac0QfVrIkcwNpSQaRHi6Ef+Nhj6TWhAZYno9g== X-Forefront-Antispam-Report: CIP:216.228.117.161; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:dc6edge2.nvidia.com; CAT:NONE; SFS:(13230040)(82310400026)(36860700016)(1800799024)(23010399003)(376014)(18002099003)(22082099003)(56012099006)(3023799007)(10067099003)(6133799003)(11063799006); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: Jnyhybk1FK0wFbJnXK/5x9qx5jDkIF2RHCo5eQDxhyqA1nr6meuz9iMtY6ZxGH0+/pPVvJfPp+FMU3KSUW9w0h2eOtGRbcqNrztl/485S6kn59QNf8fIx4caPF3tyM8O0JDXObTdY/UIQd8DLBWd182b7DUNtVilZtzT+Pta6erRDiesV0jp54zw36J7eVikZS2CSkvm+GoUPdvzpMdUUefKTsKyow9rffPCNcuGWO80B5alQWn8hjrgdvYzR9NFfoCIUvtA0AzN23mlj42Ee/wNTWM4hFeRrTuW1XAyyAYGUAocAKbMqyelQ/wAQsvIZSap408R7kTleD97SfWkAbXisz6Q9BaNEhUT8kEVsIEJPtBh4BTzm2qB7hSz4iZEUq57Ti79m8/0J0R91BUAromBHfKE8zFDH4cI6WCjPgJowjnqm49BqqKxyYtYqQdv X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 02 Sep 2026 14:53:43.8107 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: a5cbe1b4-5315-426b-aafd-08df0901fc21 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.117.161]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: SA2PEPF00001509.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR12MB7978 X-Spam-Status: No, score=-8.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FORGED_SPF_HELO, GIT_PATCH_0, KAM_SHORT, LOCAL_AUTHENTICATION_FAIL_SPF, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_NONE, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list <gcc-patches.gcc.gnu.org> List-Unsubscribe: <https://gcc.gnu.org/mailman/options/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe> List-Archive: <https://gcc.gnu.org/pipermail/gcc-patches/> List-Post: <mailto:gcc-patches@gcc.gnu.org> List-Help: <mailto:gcc-patches-request@gcc.gnu.org?subject=help> List-Subscribe: <https://gcc.gnu.org/mailman/listinfo/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe> Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org |
| Series |
Saturating arithmetic matching improvements
|
|
Commit Message
Kyrylo Tkachov
Sept. 2, 2026, 2:52 p.m. UTC
From: Kyrylo Tkachov <ktkachov@nvidia.com> For unsigned X, ~X is MAX - X. MIN (~X, Y) limits the addend to the largest value that cannot overflow. X + MIN (~X, Y) is therefore saturating addition. Recognize this form. Require the MIN to have one use so that the replacement removes it. AArch64 -O2: before: mvn w2, w0 cmp w2, w1 csel w2, w2, w1, ls add w0, w2, w0 after: adds w0, w0, w1 csinv w0, w0, wzr, cc Four instructions become two. Bootstrapped and tested on aarch64-none-linux-gnu. Ok for trunk? gcc/ChangeLog: * match-sat-alu.pd (unsigned_integer_sat_add): Add the X + MIN (~X, Y) form. gcc/testsuite/ChangeLog: * gcc.target/aarch64/sat_u_add_min_not-1.c: New test. Signed-off-by: Kyrylo Tkachov <ktkachov@nvidia.com> --- gcc/match-sat-alu.pd | 7 +++++++ .../gcc.target/aarch64/sat_u_add_min_not-1.c | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/sat_u_add_min_not-1.c
Comments
On Wed, Sep 2, 2026 at 7:59 AM <ktkachov@nvidia.com> wrote: > > From: Kyrylo Tkachov <ktkachov@nvidia.com> > > For unsigned X, ~X is MAX - X. MIN (~X, Y) limits the addend to the largest > value that cannot overflow. X + MIN (~X, Y) is therefore saturating addition. > > Recognize this form. Require the MIN to have one use so that the replacement > removes it. > > AArch64 -O2: > > before: > > mvn w2, w0 > cmp w2, w1 > csel w2, w2, w1, ls > add w0, w2, w0 > > after: > > adds w0, w0, w1 > csinv w0, w0, wzr, cc > > Four instructions become two. > > Bootstrapped and tested on aarch64-none-linux-gnu. > > Ok for trunk? > > gcc/ChangeLog: > > * match-sat-alu.pd (unsigned_integer_sat_add): Add the > X + MIN (~X, Y) form. > > gcc/testsuite/ChangeLog: > > * gcc.target/aarch64/sat_u_add_min_not-1.c: New test. > > Signed-off-by: Kyrylo Tkachov <ktkachov@nvidia.com> > --- > gcc/match-sat-alu.pd | 7 +++++++ > .../gcc.target/aarch64/sat_u_add_min_not-1.c | 18 ++++++++++++++++++ > 2 files changed, 25 insertions(+) > create mode 100644 gcc/testsuite/gcc.target/aarch64/sat_u_add_min_not-1.c > > diff --git a/gcc/match-sat-alu.pd b/gcc/match-sat-alu.pd > index 9564366d32f..b01989c3a1c 100644 > --- a/gcc/match-sat-alu.pd > +++ b/gcc/match-sat-alu.pd > @@ -68,6 +68,13 @@ along with GCC; see the file COPYING3. If not see > wide_int sum = wi::add (cst_1, cst_2); > } > (if (wi::eq_p (max, sum)))))) > + (match (unsigned_integer_sat_add @0 @1) > + /* SAT_U_ADD = X + MIN (~X, Y). ~X is MAX - X, so the MIN caps Y at the > + largest addend that does not overflow. The MIN has to be single use: > + while it stays live the saturating add is computed beside it instead of > + replacing it, which costs an instruction. */ > + (plus:c (min:c@2 (bit_not @0) @1) @0) > + (if (single_use (@2)))) Does using :cs on min work instead of the single_use? It might be useful to add a testcase where the min is used twice. Otherwise this is ok. On a follow up maybe you can recognize `~X + MIN(X, Y)` as sat u add for `~X+Y` > (match (unsigned_integer_sat_add @0 @1) > /* SUM = ADD_OVERFLOW (X, Y) > SAT_U_ADD = REALPART (SUM) | -IMAGPART (SUM) */ > diff --git a/gcc/testsuite/gcc.target/aarch64/sat_u_add_min_not-1.c b/gcc/testsuite/gcc.target/aarch64/sat_u_add_min_not-1.c > new file mode 100644 > index 00000000000..58ed36897ab > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/sat_u_add_min_not-1.c > @@ -0,0 +1,18 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-optimized" } */ > + > +typedef unsigned char u8; > +typedef unsigned short u16; > +typedef unsigned int u32; > +typedef unsigned long long u64; > + > +#define DEF(T) \ > + T f_##T (T a, T b) { T t = ~a; return a + (b < t ? b : t); } \ > + T g_##T (T a, T b) { T t = ~a; return (t < b ? t : b) + a; } > + > +DEF (u8) > +DEF (u16) > +DEF (u32) > +DEF (u64) > + > +/* { dg-final { scan-tree-dump-times "\\.SAT_ADD " 8 "optimized" } } */ > -- > 2.50.1 (Apple Git-155) >
diff --git a/gcc/match-sat-alu.pd b/gcc/match-sat-alu.pd index 9564366d32f..b01989c3a1c 100644 --- a/gcc/match-sat-alu.pd +++ b/gcc/match-sat-alu.pd @@ -68,6 +68,13 @@ along with GCC; see the file COPYING3. If not see wide_int sum = wi::add (cst_1, cst_2); } (if (wi::eq_p (max, sum)))))) + (match (unsigned_integer_sat_add @0 @1) + /* SAT_U_ADD = X + MIN (~X, Y). ~X is MAX - X, so the MIN caps Y at the + largest addend that does not overflow. The MIN has to be single use: + while it stays live the saturating add is computed beside it instead of + replacing it, which costs an instruction. */ + (plus:c (min:c@2 (bit_not @0) @1) @0) + (if (single_use (@2)))) (match (unsigned_integer_sat_add @0 @1) /* SUM = ADD_OVERFLOW (X, Y) SAT_U_ADD = REALPART (SUM) | -IMAGPART (SUM) */ diff --git a/gcc/testsuite/gcc.target/aarch64/sat_u_add_min_not-1.c b/gcc/testsuite/gcc.target/aarch64/sat_u_add_min_not-1.c new file mode 100644 index 00000000000..58ed36897ab --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sat_u_add_min_not-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned long long u64; + +#define DEF(T) \ + T f_##T (T a, T b) { T t = ~a; return a + (b < t ? b : t); } \ + T g_##T (T a, T b) { T t = ~a; return (t < b ? t : b) + a; } + +DEF (u8) +DEF (u16) +DEF (u32) +DEF (u64) + +/* { dg-final { scan-tree-dump-times "\\.SAT_ADD " 8 "optimized" } } */