From patchwork Thu Jun 16 11:08:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tamar Christina X-Patchwork-Id: 55133 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 4546A3856954 for ; Thu, 16 Jun 2022 11:09:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4546A3856954 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1655377791; bh=nCwQvYPEyKXJ+F6zStyucz2x6L/t/NCuKDdcTh08koY=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=atV/t4+LrtCokjH9Y56YArNt8tmRXqiz/q/OZ/GUGM5uRb/uUE4heYEn8wRlqnlGN RVnOkA+1EgWufUkHNgc5tGUr2bQEEtagC+Nim7cTIm8n42ts9+RlrRMTPt1kS9077v GFG/BXZuPd3sDc+Pa7yvXg73TE27XBIcDyK5DUCQ= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00058.outbound.protection.outlook.com [40.107.0.58]) by sourceware.org (Postfix) with ESMTPS id 308823856949 for ; Thu, 16 Jun 2022 11:09:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 308823856949 ARC-Seal: i=2; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=pass; b=khKbCvBwloKkelhsUzv883SEpzMCErBf2Y8bubK9rYMSllgV52OXgowAmjyxQHfjHTUk5Tj2NuuvuDlTK4RJSQiCYu/W++qPbB/6wuISKqqqC8QSNGATgs9oiRJKzOjEKwYObyLWXcSwdlWXaMsKqy9KB5uympjg3qr6j1YaJuzJAK9BUAQvnVU3BL/DoF7BKf1YM6RgwhxfXmhtZua+SwFYWoOumtQ0I9rOuYBy2QSR9UY46bFmu2xdwuBAHiKOclos4ltqwuv4c3fLhxtGmtybD99hCqU0uiLcTR/eeEKdAJjm5QCGxl9mMBbxYiWuIzAKwDgJCh8U0AFGpXEzuQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=nCwQvYPEyKXJ+F6zStyucz2x6L/t/NCuKDdcTh08koY=; b=bI7QbXK/vQIE0D7Hsj0AfgTduBl8V9YEER7GFAj6yJRTG3QrtT2yqbLBmLWt9MlgoeHEESVWnIP5V8nXnFxUeSdoBq+2tWnvkMd171u/79Liw9OS64Gg/InzCo0a49XtS6uuG969ibttG/V+al4n7OVyxpnrQfkOqA7c9nn8H3toxhxrvLLOEULKk29ugC7r99aCzdlVk0Sng5IVrYAIF1J+WBo9zz9trzE1AueGb2pB/kT02tu2lCCtkOGpg6nxGF9vUOVZjPT5M8RAjN4UU6d4oARI3JUXb3bNtGSg9/Ou8Hnq+FO1ATi2dcQmrO6u8prM2jL1IKdLM6Tjf3H4mQ== ARC-Authentication-Results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 63.35.35.123) 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=armh.onmicrosoft.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dkim=[1,1,header.d=arm.com] dmarc=[1,1,header.from=arm.com]) Received: from AM5PR0701CA0067.eurprd07.prod.outlook.com (2603:10a6:203:2::29) by DB9PR08MB6809.eurprd08.prod.outlook.com (2603:10a6:10:2ae::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5332.13; Thu, 16 Jun 2022 11:09:19 +0000 Received: from VE1EUR03FT053.eop-EUR03.prod.protection.outlook.com (2603:10a6:203:2:cafe::6a) by AM5PR0701CA0067.outlook.office365.com (2603:10a6:203:2::29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5373.9 via Frontend Transport; Thu, 16 Jun 2022 11:09:19 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; pr=C Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by VE1EUR03FT053.mail.protection.outlook.com (10.152.19.198) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5353.14 via Frontend Transport; Thu, 16 Jun 2022 11:09:18 +0000 Received: ("Tessian outbound e40990bc24d7:v120"); Thu, 16 Jun 2022 11:09:18 +0000 X-CR-MTA-TID: 64aa7808 Received: from f65efd3e5381.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id 2EB0AD88-EC44-4B74-884D-CC48DCC12698.1; Thu, 16 Jun 2022 11:08:53 +0000 Received: from EUR04-VI1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id f65efd3e5381.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Thu, 16 Jun 2022 11:08:53 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=OkZDi5WYUomGRVfxKLQJNCd5Y8yldts+YpU+i89c1zxs7bleqoUfAdoHjp/Sv4Jcp4pAxE3SB39sSeoAaeA2lGU0HpddaqL8ZYp8rn/ImgOmP5wzXBEMafphCneHbIKUdn6rdsNqeMTVka5d3iOpwTfAE9OiSQVaqy6DIFxMg+plyoGUdYPLQz4rGmpaiqa4Lrl8nHJZNdIdpnamHyTcCL8kifCh7km7z/UvwKvjJ4CzJ/qsN9G9Yhb51BT+gjWfjO6kpAEp0kB21cVjvrK+MSKcYFL/5N0m87Dl176O8kb8NJ2As4OFJWImEydl3NlSBjog9ZHmQ8SlrpmSAUV93Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=nCwQvYPEyKXJ+F6zStyucz2x6L/t/NCuKDdcTh08koY=; b=D2rthKiZg9jzeaH74Y+Vink9RV624VCXtYxP+CpEMFpvvuwvKXF2X5/VmzgEY2givmnvsDQ3I5+57930eFNH+vp7XsKFHiPo5ZgaeavDQv6yHGP5to7+ETcbGL/fm+QP5Ot5hrrTGD6HNLTeacC6QRplPXOtpkxz9YswxNJtBQiSTyUHWX13J8bViZvEAPEHqk78Z8MqtzFp9zzctliSK6H8+sARmhsswOjHKyEnZsUKqMfSnkiDmu6KtnFaRarcEuCaL00PCbevPS/88LC5zpa1eI1O88wnwzZKV9POpC9bTAaxA3njlJIWhZCiJ130pUXPyUUmxaySWydaiDCf8A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none Authentication-Results-Original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; Received: from VI1PR08MB5325.eurprd08.prod.outlook.com (2603:10a6:803:13e::17) by DB9PR08MB6779.eurprd08.prod.outlook.com (2603:10a6:10:2a1::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5353.15; Thu, 16 Jun 2022 11:08:50 +0000 Received: from VI1PR08MB5325.eurprd08.prod.outlook.com ([fe80::54e5:594b:e5fd:a9b4]) by VI1PR08MB5325.eurprd08.prod.outlook.com ([fe80::54e5:594b:e5fd:a9b4%8]) with mapi id 15.20.5353.014; Thu, 16 Jun 2022 11:08:49 +0000 Date: Thu, 16 Jun 2022 12:08:47 +0100 To: gcc-patches@gcc.gnu.org Subject: [PATCH 1/2]middle-end: Simplify subtract where both arguments are being bitwise inverted. Message-ID: Content-Disposition: inline X-ClientProxiedBy: LO4P123CA0002.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:150::7) To VI1PR08MB5325.eurprd08.prod.outlook.com (2603:10a6:803:13e::17) MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: 6e41db09-34ac-4b7e-36ac-08da4f88a88c X-MS-TrafficTypeDiagnostic: DB9PR08MB6779:EE_|VE1EUR03FT053:EE_|DB9PR08MB6809:EE_ X-Microsoft-Antispam-PRVS: x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: VxvSPynopVByKvUJxQSufE8BUgYki9XJcktuUtJyBeTfrjIhuceLV7Ls9fD7c/3hWyyJkwI75nwG+U1mXdwHe5bHVGxo3yWg4Q4dS6RJa6bN3TlX/lycx9kJQYBtRpS3QXp5qdAGJxMYv018kMj6xarHtjOEug9jJmwIHkqpuZLWuVwYJBisqnlpUM0Qp6npKmhCxXY7mqMlnsrTJa49t7H676oK9YADZCpDn55Tm8AJaVw9XP7P7xDEIk71/syFpC9rg4CdIOAwPhVjkzl580ErFvL9rP4JMogDJChV/JzNVzpVqPQg/wZiqJ9OuwxTIMSh/mmRm7Ig9O31Ga8QOCklSZjc9xDKwesX6Ie5ydczKn76Aa/bmAdrPLNY+oXhZPfZIYsKUipdMkDGEFIxPf1AcYQs1rPZ4Er7WaEBRFgkY/1z5n4py+fuhHg+yymjxE3Y4IJYMhsj2R6bT8CAZpyrTKXyASVg2brznt5v+GQpvB4Mj35MD+do2xaddPTRaHlDIJ9SazkDTbwAeqLyRZxATIMLZI6cW/yPgywMqpQZZRCAFEOq1y+U+w5OUX/rb2KGDKdvabEqraRs+UVu8c0Zpgp/MasZvTM5dpSvFh/4nZocTYZlaBpC8aUMIOWSUX/UjoBw7ozRHRDu86bQw1y/XrSFhsH7BfHboYLtrR+Ea/E2oyq/yA+5FR+A+UViiud43fiG0rpxRH8C1ilciVlB9Xo2bV8l1zF1E1JtDprtu3TW6QdOVJlHTt0F8dBUHt5CR7l4rZRvg7m7YkH1btj5IjO6BiRoqb/T/oOxXxJrmZCSEnehlvA2CnjjyOMQ X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1PR08MB5325.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230016)(4636009)(366004)(44144004)(33964004)(186003)(6506007)(26005)(4743002)(2616005)(6512007)(84970400001)(38100700002)(83380400001)(235185007)(4326008)(8676002)(44832011)(8936002)(86362001)(5660300002)(2906002)(6916009)(6486002)(316002)(66556008)(508600001)(66476007)(66946007)(36756003)(4216001)(2700100001); DIR:OUT; SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR08MB6779 Original-Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: VE1EUR03FT053.eop-EUR03.prod.protection.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: 354040a6-51be-438b-6ef1-08da4f88970e X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 69iS+2mhE4RMmHEPqA3zHFJeiKee+FoYfwgil1aP4M4wdwPxI7BzcTMfWGqcRVdv180ob9Cl8qczh2dYZQZdJ7eHayH88+quNWMuY6Ghmle0QLZ223/+yprKnnr/dwkRH3gZCzFiUPAVfCYssVCK6S4IesYZ3uDlxrWc7ItMSRc640vbFvRtXvb3Kr/Mz6VKRgDbsGXoo8RTdYHqV+NPDrKl9gn2r2VrkIRryS38N2icuXGN0bKMQpKg2Sa0J8GoeZr2sUSy1bPYgUSzoLM9t1BzmmO8XeyCbWfmgcdQiJxgCJcai/TZcmjKxjcTfWK51qeQba8bQ7dCMIIOnaxBlE5HKLC37Php99lAYVpKDcZZ1AMB/CwGxY/QQ9ymEQp3ySgILiHxBnCh/BQ8RCGDJgTC4VzI0NkTbgebKQuMHM3qV9IhQpLcAj6Fxk4W0Z0H8/CFH3spZhYduwkpfAdO9ZJanpZOmlNUu3xDQUuWxsC/oDqzA97y4h6DHhEMOo0kg+1yqF1W1Et7zxZToJ13AsKEfXpu8bKIq8Pfv7enBc4m7DHU6EbPWUQQKIoTsMlkrwx3xSMc2A74s/XhaLrgLafuyUrFuHCH/PwU30jdTNzDAVWqtNyf4L6YHgq3RVyAvjqdH+jH5a1zbkAD+DGjghqRSeCrMCHDPJ6vUPt2Cqz3mlqPSLIxXC2mFZ7OQ89n7yAlZZLP1Bft5eZJeb6EhqoLAQLYBOkdt4TlB2eBOHYVFVibTqLnP+4o7D984etRQmz3INERoMuPjk8i4nD8Wnw6ijnjGgfCBFFxUa6hVm5fTMnwG02Acrh5FGyXoldy X-Forefront-Antispam-Report: CIP:63.35.35.123; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:64aa7808-outbound-1.mta.getcheckrecipient.com; PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com; CAT:NONE; SFS:(13230016)(4636009)(40470700004)(46966006)(36840700001)(84970400001)(26005)(6512007)(36860700001)(86362001)(4743002)(81166007)(336012)(6506007)(47076005)(33964004)(2616005)(40460700003)(107886003)(186003)(70586007)(36756003)(4326008)(8936002)(6916009)(8676002)(5660300002)(2906002)(316002)(235185007)(70206006)(508600001)(6486002)(44832011)(82310400005)(44144004)(356005)(83380400001)(4216001)(2700100001); DIR:OUT; SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Jun 2022 11:09:18.7160 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 6e41db09-34ac-4b7e-36ac-08da4f88a88c X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[63.35.35.123]; Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: VE1EUR03FT053.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR08MB6809 X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, FORGED_SPF_HELO, GIT_PATCH_0, KAM_DMARC_NONE, KAM_LOTSOFHASH, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE, UNPARSEABLE_RELAY 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tamar Christina via Gcc-patches From: Tamar Christina Reply-To: Tamar Christina Cc: nd@arm.com, rguenther@suse.de Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi All, This adds a match.pd rule that drops the bitwwise nots when both arguments to a subtract is inverted. i.e. for: float g(float a, float b) { return ~(int)a - ~(int)b; } we instead generate float g(float a, float b) { return (int)a - (int)b; } We already do a limited version of this from the fold_binary fold functions but this makes a more general version in match.pd that applies more often. Bootstrapped Regtested on aarch64-none-linux-gnu and no issues. Ok for master? Thanks, Tamar gcc/ChangeLog: * match.pd: New bit_not rule. gcc/testsuite/ChangeLog: * gcc.dg/subnot.c: New test. --- inline copy of patch -- diff --git a/gcc/match.pd b/gcc/match.pd index a59b6778f661cf9121dd3503f43472871e4da445..51b0a1b562409af535e53828a10c30b8a3e1ae2e 100644 --- diff --git a/gcc/match.pd b/gcc/match.pd index a59b6778f661cf9121dd3503f43472871e4da445..51b0a1b562409af535e53828a10c30b8a3e1ae2e 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1258,6 +1258,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (simplify (bit_not (plus:c (bit_not @0) @1)) (minus @0 @1)) +/* (~X - ~Y) -> X - Y. */ +(simplify + (minus (bit_not @0) (bit_not @1)) + (minus @0 @1)) /* ~(X - Y) -> ~X + Y. */ (simplify diff --git a/gcc/testsuite/gcc.dg/subnot.c b/gcc/testsuite/gcc.dg/subnot.c new file mode 100644 index 0000000000000000000000000000000000000000..d621bacd27bd3d19a010e4c9f831aa77d28bd02d --- /dev/null +++ b/gcc/testsuite/gcc.dg/subnot.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +float g(float a, float b) +{ + return ~(int)a - ~(int)b; +} + +/* { dg-final { scan-tree-dump-not "~" "optimized" } } */ --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1258,6 +1258,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (simplify (bit_not (plus:c (bit_not @0) @1)) (minus @0 @1)) +/* (~X - ~Y) -> X - Y. */ +(simplify + (minus (bit_not @0) (bit_not @1)) + (minus @0 @1)) /* ~(X - Y) -> ~X + Y. */ (simplify diff --git a/gcc/testsuite/gcc.dg/subnot.c b/gcc/testsuite/gcc.dg/subnot.c new file mode 100644 index 0000000000000000000000000000000000000000..d621bacd27bd3d19a010e4c9f831aa77d28bd02d --- /dev/null +++ b/gcc/testsuite/gcc.dg/subnot.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +float g(float a, float b) +{ + return ~(int)a - ~(int)b; +} + +/* { dg-final { scan-tree-dump-not "~" "optimized" } } */ From patchwork Thu Jun 16 11:09:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tamar Christina X-Patchwork-Id: 55134 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 B8EE0385694B for ; Thu, 16 Jun 2022 11:11:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B8EE0385694B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1655377867; bh=u4d+DxsA3N+wuoc0LsSFjD+cs07nBf4z+D0XkpPqzk0=; h=Date:To:Subject:In-Reply-To:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=cJ/xmRVSfzZD+TFXOuI3cSRB4Xe517gJN8BCOAhYSgERuSwksx3s+xwtPPdXRjAZS 2j45HtukjSvzQwjb2zVUw5NpUFv6iU0L/mk9urRrs8x3Aolqn31oMPAvltXrrq9Ww1 AFxx3JlPFbZP01CREVaIqE3DmRszzMJx1/kZOb0g= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from EUR03-AM5-obe.outbound.protection.outlook.com (mail-eopbgr30049.outbound.protection.outlook.com [40.107.3.49]) by sourceware.org (Postfix) with ESMTPS id E123B3856949 for ; Thu, 16 Jun 2022 11:10:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E123B3856949 ARC-Seal: i=2; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=pass; b=X7Pd/yvCuzpQlQW6FyqEW1XWl/pYd1sjIymsbQo4YdjxGtqzAFmwbtyUSuFfgZ6UAlDizKgO6tdPihqIS7VZo4nDtCu2Hm85UFCOBm9k9GjIQxiC2XV4FvE3LMq3V5zg08/Th14QZfWqdEIGoD0j6DE1bvvcwZh7iujjMvXvWCHB2wZWeRVmDEwAiW78z7CmX76HURpxeGhwt8kWPl2VxELU5C+c2MZSD14pWhFs5VczMuR/Hc97rftwILALBiw50JWjBcfzUBMOvi6s03XpSpNgoa1IKwNz+Ch1WPv/BjeTxE6hpaziOWUsXvVNGH0DoCqA7rnFfzlrm13TfFNnBg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=u4d+DxsA3N+wuoc0LsSFjD+cs07nBf4z+D0XkpPqzk0=; b=ILhiBaZ/Uwjt0yA6kFU4s7/ysS2/PlmRHhrO5DFVw9nh5NwOPP7x1+LJ5CzQ54y7la5vCemGNmP3hWG9WYBCnoIOLyKZTN90TDoPfL8SiC2aXXGdT8wbfP23IR1XVgbpcbpmsbWyHHygMoZbGT7nBmUdqYVRBmcfIckSvYT/KNvIYFa6n0Yiw6Ib4Fwd+wf527b6nPBkNB2e0zvx9q4lPtpcFFIcueTtlknctMcQMsKe2/jfUBkWH0Uo9+voT99cFqv9QGhHRLp6fipePQnqfrr1MW7K72OgqaYAbR5VGBlTc1p3viboCe9yC+rhfPQJquVk8MvAlxYQol3o71ryHQ== ARC-Authentication-Results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 63.35.35.123) 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=armh.onmicrosoft.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dkim=[1,1,header.d=arm.com] dmarc=[1,1,header.from=arm.com]) Received: from AS8P189CA0040.EURP189.PROD.OUTLOOK.COM (2603:10a6:20b:458::7) by DB6PR0802MB2390.eurprd08.prod.outlook.com (2603:10a6:4:9f::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5332.16; Thu, 16 Jun 2022 11:10:29 +0000 Received: from AM5EUR03FT005.eop-EUR03.prod.protection.outlook.com (2603:10a6:20b:458:cafe::96) by AS8P189CA0040.outlook.office365.com (2603:10a6:20b:458::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5353.14 via Frontend Transport; Thu, 16 Jun 2022 11:10:29 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; pr=C Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by AM5EUR03FT005.mail.protection.outlook.com (10.152.16.146) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5353.14 via Frontend Transport; Thu, 16 Jun 2022 11:10:29 +0000 Received: ("Tessian outbound ff2e13d26e0f:v120"); Thu, 16 Jun 2022 11:10:29 +0000 X-CR-MTA-TID: 64aa7808 Received: from 28d949eb43e2.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id 2CAC37A0-9451-4782-989D-910015F8803A.1; Thu, 16 Jun 2022 11:10:05 +0000 Received: from EUR04-VI1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id 28d949eb43e2.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Thu, 16 Jun 2022 11:10:05 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=SzRYnKa0e/OpE3glJWF3bsMAVgJ3LVJFiGxGrhMe6i86k5+70gp//5K4Hps99oY1pApcxeUhaARmKL2wEHR0Ouq4nuz3gD6BQ1KxXBvMFDXMRihnqqV1DNHz14IqPb8DlYZa4rVZ05SIpaifMLQLSh9vUCSmrGBQtVynZVmzodlEzxsjK8Xtgy1lrBE3w+x1EblW08hLVZTZwlvZfSAEwx86ruXEKAJfUawP++XM34pSL62RxTio+As6AOqMrSB+/X6IuwQLNXrRyBLGHTWo0W7baLSYg+E5k8h+BZaNE1JaC+yQV6ExJlh4DE1IlbGHQoPsKLoljTcuNH7EJ5YgCQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=u4d+DxsA3N+wuoc0LsSFjD+cs07nBf4z+D0XkpPqzk0=; b=CIpojNxnlMyprzPlbhlyW+muV4ZBjd+YfD7QaxkJThDFiIqAiiXgzqxmDjV0vOLGt3AvTj+mxw0zQ+EahOwQmjdPOuxfUciIWvJ/PzLwLSfQxK+CvQxAQdC1Y39xLQXjsxmHL8pg4lSdiUH4U9WWc5PyX4uXWMTXBoZ/M8AC1KpSWRapzyVdAu1EBivVbDSm6nLuMaDlbBG6hF7Wn81CzxeUYdu9BQFNg9rdVXbjuCJ0QUP7qlj6SLhReji4O82emzRvvaiyXKkzU3ZFuDVby6jGBTeZDV6KHYH9SdC60FVd/2JwSOQw0YYYEyXq/6lz6J+Xr4Nz5MfELCPx45KKCg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none Authentication-Results-Original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; Received: from VI1PR08MB5325.eurprd08.prod.outlook.com (2603:10a6:803:13e::17) by DB9PR08MB6779.eurprd08.prod.outlook.com (2603:10a6:10:2a1::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5353.15; Thu, 16 Jun 2022 11:10:02 +0000 Received: from VI1PR08MB5325.eurprd08.prod.outlook.com ([fe80::54e5:594b:e5fd:a9b4]) by VI1PR08MB5325.eurprd08.prod.outlook.com ([fe80::54e5:594b:e5fd:a9b4%8]) with mapi id 15.20.5353.014; Thu, 16 Jun 2022 11:10:01 +0000 Date: Thu, 16 Jun 2022 12:09:59 +0100 To: gcc-patches@gcc.gnu.org Subject: [PATCH 2/2]middle-end: Support recognition of three-way max/min. Message-ID: Content-Disposition: inline In-Reply-To: X-ClientProxiedBy: LO2P265CA0278.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:a1::26) To VI1PR08MB5325.eurprd08.prod.outlook.com (2603:10a6:803:13e::17) MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: 862c68b2-d502-4499-ccb8-08da4f88d2bd X-MS-TrafficTypeDiagnostic: DB9PR08MB6779:EE_|AM5EUR03FT005:EE_|DB6PR0802MB2390:EE_ X-Microsoft-Antispam-PRVS: x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: P9Eb+741XOVWG2A7a2zX5yVQFn2FidXjE7w2UvkxG5R0eYUQKkR91QhyueXM1O93wJAztBPmyIOD2pLFcNRMYEO9cVkKtKXxJBNaNfNtkLSAW7fhHCar7KdJNdHSqn+f1oYyCp3cQ+MpED2YvL+h9+vzeJHI04OBcmTeB0Aw1gCCAp/imhv2+7nDtpNSrQDg2MmGc+YCRJ3ka7/1YhbVG3aIJyd7930sd3JTNRXM1zWpOWItm9VxdpKjwW2Ay/IZ4jMJxPZYnE9zpHI9DwtOVVj0BbddgcUMdsEgmTIf9agNQsdbWyk7uLqL7dmnRKlzWNXzRe0sVwFD6tYPeC4qRv61kaDBvCGmSCcPXDH00jHzPHhkEmSH3pB71hS8jZ75utIwt5B0m6J74XoavfPWOj9KLVL48EbURs87ggTJWR6E5QBT+QY9RyqNn3Pyo/MBqLEH11/8rBj+QtbeZL/8Twt3YOHcI0D7zHwUgNmhZpCcld3/WAQS9D6xD19gmZA1bCzQKtN5As5AGp47xDFL/WapKCtt/iuFApx65C8snMd8uKk5CAKCu7IpOIpQi6Y+R1xnRH06WBif2SfVoKoALNa9yJn5ygFZ9lyqz2cABoggJpZJgj/Af/IM3Mxd4QkxEFvkcPgFdhOHDdkHRd+LTHrS+a08eUQeP+xMBV3T419JpKVIxI4ydLO3qoTQt7o5L5YeY97Wdek3JiRAT1vd8Vypb78KRmohyP51FzM8pH6GhDt4/xRmmK3GqqOj8pjovjXRxO/rAo9jODu6BlewLFQx1xSLqaFHIgpi/BFl1Lnxh+qVGr1ffiyzFLVoOtW0wJjX3XlRMcoHGV9nalDQ/w== X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1PR08MB5325.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230016)(4636009)(366004)(86362001)(5660300002)(235185007)(4326008)(44832011)(8936002)(8676002)(30864003)(2906002)(508600001)(66556008)(66476007)(66946007)(36756003)(6916009)(6486002)(316002)(2616005)(4743002)(6506007)(26005)(44144004)(33964004)(186003)(38100700002)(84970400001)(83380400001)(6512007)(2700100001); DIR:OUT; SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR08MB6779 Original-Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: AM5EUR03FT005.eop-EUR03.prod.protection.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: 0083bf3a-32ea-4e23-7e0d-08da4f88c206 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: CtfCCrqs7x5m0Pbxx/hojV+lDrulZ/Khd041AjgZ9oUWRDl4ynBU/lwcwJjgDvUJL90KUCYo60ogQRl6osm0764CAdpAjF4U8qtCs5NdYpoeQ6rpGKf7KsVVfmSfDAkTbYocz3qVkT/FLZOd85Hyqk4BzlZfa9eO07sRILhRCiUOMEy+cZFvHGaGOIvCtIUrdwylIbazUb7P9eYYLoSGwXWg07zsRSNfPOvAXAhQyd47Mg4xMlOceamwis0g05EjMOwEZf2G9TmwKQ6REbXUrtFhOHmxyFhcu2zr22Lgc57GmM84wu61KsX6R67cnVyQ5QIDobJpG+KxBF/xfjOk1SBkUsLjfAeo1SVqoLepbH3ivHVpXXXkDI64EjgjbOUOxVoeflVd/M6DV4h/x9/G8SejnT1iOprIe3TqSPGNHHhYtQiAECM/uR11cyjnAXmToKwDtn+ReI8qAlybEukuYzDQo9PewSr6ZtEny0za0xxfmbSjx3HO5YCJOwqGxNI988v+6Mpg6gHj0sWKM6RgZV7RyW3NEzwyiwBjyzsiaknHaDauHrkNkLcUFsGwDBg4/dY60rM8YLVUcSiohmAI/JXkn2LDiwEdpY+o5o1MECYyIlDlTrlVdD9QMsM3+LWHyjsd9Epp12kP5FiFLBqEvwX/QbIxnmHm7eLynywkWZsY4wXQnWjstZTltQJz4bpmPWEY7zG0eXTvP2228l/9HCMvrHeEyepoKF0fXZa7I7+uTiUcaVeiuQ0ROUmYw0Oj3YGsNYBUGmWTfVfOVz7QKI+XYRGITYqNu5J9q4a/Ro5KVR/sDlF7JQb4qdxMcNZu1aw2xooB9oZHmsUBb2igAQ== X-Forefront-Antispam-Report: CIP:63.35.35.123; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:64aa7808-outbound-1.mta.getcheckrecipient.com; PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com; CAT:NONE; SFS:(13230016)(4636009)(36840700001)(40470700004)(46966006)(8676002)(70206006)(70586007)(2616005)(4326008)(47076005)(356005)(36756003)(107886003)(508600001)(186003)(84970400001)(316002)(6486002)(36860700001)(82310400005)(86362001)(40460700003)(83380400001)(8936002)(336012)(30864003)(5660300002)(235185007)(6916009)(6512007)(33964004)(26005)(2906002)(4743002)(6506007)(44832011)(81166007)(44144004)(2700100001); DIR:OUT; SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Jun 2022 11:10:29.5365 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 862c68b2-d502-4499-ccb8-08da4f88d2bd X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[63.35.35.123]; Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: AM5EUR03FT005.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB6PR0802MB2390 X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, FORGED_SPF_HELO, GIT_PATCH_0, KAM_DMARC_NONE, KAM_LOTSOFHASH, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE, UNPARSEABLE_RELAY 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tamar Christina via Gcc-patches From: Tamar Christina Reply-To: Tamar Christina Cc: jakub@redhat.com, nd@arm.com, rguenther@suse.de Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi All, This patch adds support for three-way min/max recognition in phi-opts. Concretely for e.g. #include uint8_t three_min (uint8_t xc, uint8_t xm, uint8_t xy) { uint8_t xk; if (xc < xm) { xk = (uint8_t) (xc < xy ? xc : xy); } else { xk = (uint8_t) (xm < xy ? xm : xy); } return xk; } we generate: [local count: 1073741824]: _5 = MIN_EXPR ; _7 = MIN_EXPR ; return _7; instead of : if (xc_2(D) < xm_3(D)) goto ; else goto ; : xk_5 = MIN_EXPR ; goto ; : xk_6 = MIN_EXPR ; : # xk_1 = PHI return xk_1; The same function also immediately deals with turning a minimization problem into a maximization one if the results are inverted. We do this here since doing it in match.pd would end up changing the shape of the BBs and adding additional instructions which would prevent various optimizations from working. Bootstrapped Regtested on aarch64-none-linux-gnu and no issues. Ok for master? Thanks, Tamar gcc/ChangeLog: * tree-ssa-phiopt.cc (minmax_replacement): Optionally search for the phi sequence of a three-way conditional. (replace_phi_edge_with_variable): Support deferring of BB removal. (tree_ssa_phiopt_worker): Detect diamond phi structure for three-way min/max. (strip_bit_not, invert_minmax_code): New. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/split-path-1.c: Disable phi-opts so we don't optimize code away. * gcc.dg/tree-ssa/minmax-3.c: New test. * gcc.dg/tree-ssa/minmax-4.c: New test. * gcc.dg/tree-ssa/minmax-5.c: New test. * gcc.dg/tree-ssa/minmax-6.c: New test. * gcc.dg/tree-ssa/minmax-7.c: New test. * gcc.dg/tree-ssa/minmax-8.c: New test. --- inline copy of patch -- diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-3.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-3.c new file mode 100644 index 0000000000000000000000000000000000000000..de3b2e946e81701e3b75f580e6a843695a05786e --- diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-3.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-3.c new file mode 100644 index 0000000000000000000000000000000000000000..de3b2e946e81701e3b75f580e6a843695a05786e --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-3.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-phiopt" } */ + +#include + +uint8_t three_min (uint8_t xc, uint8_t xm, uint8_t xy) { + uint8_t xk; + if (xc < xm) { + xk = (uint8_t) (xc < xy ? xc : xy); + } else { + xk = (uint8_t) (xm < xy ? xm : xy); + } + return xk; +} + +/* { dg-final { scan-tree-dump-times "MIN_EXPR" 3 "phiopt1" } } */ +/* { dg-final { scan-tree-dump-times "MAX_EXPR" 0 "phiopt1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-4.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-4.c new file mode 100644 index 0000000000000000000000000000000000000000..0b6d667be868c2405eaefd17cb522da44bafa0e2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-4.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-phiopt" } */ + +#include + +uint8_t three_max (uint8_t xc, uint8_t xm, uint8_t xy) { + uint8_t xk; + if (xc > xm) { + xk = (uint8_t) (xc > xy ? xc : xy); + } else { + xk = (uint8_t) (xm > xy ? xm : xy); + } + return xk; +} + +/* { dg-final { scan-tree-dump-times "MIN_EXPR" 0 "phiopt1" } } */ +/* { dg-final { scan-tree-dump-times "MAX_EXPR" 3 "phiopt1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-5.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-5.c new file mode 100644 index 0000000000000000000000000000000000000000..650601a3cc75d09a9e6e54a35f5b9993074f8510 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-5.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-phiopt" } */ + +#include + +uint8_t three_minmax1 (uint8_t xc, uint8_t xm, uint8_t xy) { + uint8_t xk; + if (xc > xm) { + xk = (uint8_t) (xc < xy ? xc : xy); + } else { + xk = (uint8_t) (xm < xy ? xm : xy); + } + return xk; +} + +/* { dg-final { scan-tree-dump-times "MIN_EXPR" 2 "phiopt1" } } */ +/* { dg-final { scan-tree-dump-times "MAX_EXPR" 1 "phiopt1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-6.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-6.c new file mode 100644 index 0000000000000000000000000000000000000000..a628f6d99222958cfd8c410f0e85639e3a49dd4b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-6.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-phiopt" } */ + +#include + +uint8_t three_minmax3 (uint8_t xc, uint8_t xm, uint8_t xy) { + uint8_t xk; + if (xc > xm) { + xk = (uint8_t) (xy < xc ? xc : xy); + } else { + xk = (uint8_t) (xm < xy ? xm : xy); + } + return xk; +} + +/* { dg-final { scan-tree-dump-times "MIN_EXPR" 1 "phiopt1" } } */ +/* { dg-final { scan-tree-dump-times "MAX_EXPR" 1 "phiopt1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-7.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-7.c new file mode 100644 index 0000000000000000000000000000000000000000..cb42412c4ada433b2f59df0a8bef9fa7b1c5e104 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-7.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-phiopt" } */ + +#include + +uint8_t three_minmax2 (uint8_t xc, uint8_t xm, uint8_t xy) { + uint8_t xk; + if (xc > xm) { + xk = (uint8_t) (xc > xy ? xc : xy); + } else { + xk = (uint8_t) (xm < xy ? xm : xy); + } + return xk; +} +/* { dg-final { scan-tree-dump-times "MIN_EXPR" 1 "phiopt1" } } */ +/* { dg-final { scan-tree-dump-times "MAX_EXPR" 1 "phiopt1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-8.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-8.c new file mode 100644 index 0000000000000000000000000000000000000000..9cd050e932376bc50bd6ae60cb654fcab0bfdd1c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-8.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-phiopt" } */ + +#include + +uint8_t three_minmax11 (uint8_t xc, uint8_t xm, uint8_t xy) { + uint8_t xk; + if (xc < xm) { + xk = (uint8_t) (xc > xy ? xc : xy); + } else { + xk = (uint8_t) (xm > xy ? xm : xy); + } + return xk; +} + +/* { dg-final { scan-tree-dump-times "MIN_EXPR" 1 "phiopt1" } } */ +/* { dg-final { scan-tree-dump-times "MAX_EXPR" 2 "phiopt1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-1.c b/gcc/testsuite/gcc.dg/tree-ssa/split-path-1.c index 8b23ef4c7a3484cdc1647ee6d1b150f15685beff..902dde44a50e171b4f34ba7247d75a32d2c860ed 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/split-path-1.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-O2 -fsplit-paths -fdump-tree-split-paths-details --param max-jump-thread-duplication-stmts=20" } */ +/* { dg-options "-O2 -fsplit-paths -fdump-tree-split-paths-details --param max-jump-thread-duplication-stmts=20 -fno-ssa-phiopt" } */ #include #include diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc index 562468b7f02a9ffe2713318add551902c14f89c3..6246f054006ff16e73602e7ce2e367d2d21421b1 100644 --- a/gcc/tree-ssa-phiopt.cc +++ b/gcc/tree-ssa-phiopt.cc @@ -62,8 +62,8 @@ static gphi *factor_out_conditional_conversion (edge, edge, gphi *, tree, tree, gimple *); static int value_replacement (basic_block, basic_block, edge, edge, gphi *, tree, tree); -static bool minmax_replacement (basic_block, basic_block, - edge, edge, gphi *, tree, tree); +static bool minmax_replacement (basic_block, basic_block, basic_block, + edge, edge, gphi *, tree, tree, bool); static bool spaceship_replacement (basic_block, basic_block, edge, edge, gphi *, tree, tree); static bool cond_removal_in_builtin_zero_pattern (basic_block, basic_block, @@ -73,7 +73,7 @@ static bool cond_store_replacement (basic_block, basic_block, edge, edge, hash_set *); static bool cond_if_else_store_replacement (basic_block, basic_block, basic_block); static hash_set * get_non_trapping (); -static void replace_phi_edge_with_variable (basic_block, edge, gphi *, tree); +static void replace_phi_edge_with_variable (basic_block, edge, gphi *, tree, bool); static void hoist_adjacent_loads (basic_block, basic_block, basic_block, basic_block); static bool gate_hoist_loads (void); @@ -199,6 +199,7 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p) basic_block bb1, bb2; edge e1, e2; tree arg0, arg1; + bool diamond_minmax_p = false; bb = bb_order[i]; @@ -265,6 +266,29 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p) hoist_adjacent_loads (bb, bb1, bb2, bb3); continue; } + else if (EDGE_SUCC (bb1, 0)->dest == EDGE_SUCC (bb2, 0)->dest + && single_succ_p (bb1) + && single_succ_p (bb2) + && single_pred_p (bb1) + && single_pred_p (bb2) + && single_succ_p (EDGE_SUCC (bb1, 0)->dest)) + { + gimple_stmt_iterator it1 = gsi_start_nondebug_after_labels_bb (bb1); + gimple_stmt_iterator it2 = gsi_start_nondebug_after_labels_bb (bb2); + if (gsi_one_before_end_p (it1) && gsi_one_before_end_p (it2)) + { + gimple *stmt1 = gsi_stmt (it1); + gimple *stmt2 = gsi_stmt (it2); + if (is_gimple_assign (stmt1) && is_gimple_assign (stmt2)) + { + enum tree_code code1 = gimple_assign_rhs_code (stmt1); + enum tree_code code2 = gimple_assign_rhs_code (stmt2); + diamond_minmax_p + = (code1 == MIN_EXPR || code1 == MAX_EXPR) + && (code2 == MIN_EXPR || code2 == MAX_EXPR); + } + } + } else continue; @@ -316,6 +340,13 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p) if (!candorest) continue; + /* Check that we're looking for nested phis. */ + if (phis == NULL && diamond_minmax_p) + { + phis = phi_nodes (EDGE_SUCC (bb2, 0)->dest); + e2 = EDGE_SUCC (bb2, 0); + } + phi = single_non_singleton_phi_for_edges (phis, e1, e2); if (!phi) continue; @@ -329,6 +360,7 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p) gphi *newphi; if (single_pred_p (bb1) + && !diamond_minmax_p && (newphi = factor_out_conditional_conversion (e1, e2, phi, arg0, arg1, cond_stmt))) @@ -343,20 +375,25 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p) } /* Do the replacement of conditional if it can be done. */ - if (!early_p && two_value_replacement (bb, bb1, e2, phi, arg0, arg1)) + if (!early_p + && !diamond_minmax_p + && two_value_replacement (bb, bb1, e2, phi, arg0, arg1)) cfgchanged = true; - else if (match_simplify_replacement (bb, bb1, e1, e2, phi, - arg0, arg1, - early_p)) + else if (!diamond_minmax_p + && match_simplify_replacement (bb, bb1, e1, e2, phi, + arg0, arg1, early_p)) cfgchanged = true; else if (!early_p + && !diamond_minmax_p && single_pred_p (bb1) && cond_removal_in_builtin_zero_pattern (bb, bb1, e1, e2, phi, arg0, arg1)) cfgchanged = true; - else if (minmax_replacement (bb, bb1, e1, e2, phi, arg0, arg1)) + else if (minmax_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1, + diamond_minmax_p)) cfgchanged = true; else if (single_pred_p (bb1) + && !diamond_minmax_p && spaceship_replacement (bb, bb1, e1, e2, phi, arg0, arg1)) cfgchanged = true; } @@ -385,7 +422,7 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p) static void replace_phi_edge_with_variable (basic_block cond_block, - edge e, gphi *phi, tree new_tree) + edge e, gphi *phi, tree new_tree, bool delete_bb = true) { basic_block bb = gimple_bb (phi); gimple_stmt_iterator gsi; @@ -428,7 +465,7 @@ replace_phi_edge_with_variable (basic_block cond_block, edge_to_remove = EDGE_SUCC (cond_block, 1); else edge_to_remove = EDGE_SUCC (cond_block, 0); - if (EDGE_COUNT (edge_to_remove->dest->preds) == 1) + if (EDGE_COUNT (edge_to_remove->dest->preds) == 1 && delete_bb) { e->flags |= EDGE_FALLTHRU; e->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE); @@ -1564,15 +1601,52 @@ value_replacement (basic_block cond_bb, basic_block middle_bb, return 0; } +/* If VAR is an SSA_NAME that points to a BIT_NOT_EXPR then return the TREE for + the value being inverted. */ + +static tree +strip_bit_not (tree var) +{ + if (TREE_CODE (var) != SSA_NAME) + return NULL_TREE; + + gimple *assign = SSA_NAME_DEF_STMT (var); + if (gimple_code (assign) != GIMPLE_ASSIGN) + return NULL_TREE; + + if (gimple_assign_rhs_code (assign) != BIT_NOT_EXPR) + return NULL_TREE; + + return gimple_assign_rhs1 (assign); +} + +/* Invert a MIN to a MAX or a MAX to a MIN expression CODE. */ + +enum tree_code +invert_minmax_code (enum tree_code code) +{ + switch (code) { + case MIN_EXPR: + return MAX_EXPR; + case MAX_EXPR: + return MIN_EXPR; + default: + gcc_unreachable (); + } +} + /* The function minmax_replacement does the main work of doing the minmax replacement. Return true if the replacement is done. Otherwise return false. BB is the basic block where the replacement is going to be done on. ARG0 - is argument 0 from the PHI. Likewise for ARG1. */ + is argument 0 from the PHI. Likewise for ARG1. + + If THREEWAY_P then expect the BB to be laid out in diamond shape with each + BB containing only a MIN or MAX expression. */ static bool -minmax_replacement (basic_block cond_bb, basic_block middle_bb, - edge e0, edge e1, gphi *phi, tree arg0, tree arg1) +minmax_replacement (basic_block cond_bb, basic_block middle_bb, basic_block alt_middle_bb, + edge e0, edge e1, gphi *phi, tree arg0, tree arg1, bool threeway_p) { tree result; edge true_edge, false_edge; @@ -1727,9 +1801,14 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, if (false_edge->dest == middle_bb) false_edge = EDGE_SUCC (false_edge->dest, 0); + /* When THREEWAY_P then e1 will point to the edge of the final transition + from middle-bb to end. */ if (true_edge == e0) { - gcc_assert (false_edge == e1); + if (threeway_p) + gcc_assert (false_edge == EDGE_PRED (e1->src, 0)); + else + gcc_assert (false_edge == e1); arg_true = arg0; arg_false = arg1; } @@ -1768,6 +1847,133 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, else return false; } + else if (middle_bb != alt_middle_bb && threeway_p) + { + /* Recognize the following case: + + if (smaller < larger) + a = MIN (smaller, c); + else + b = MIN (larger, c); + x = PHI + + This is equivalent to + + a = MIN (smaller, c); + x = MIN (larger, a); */ + + gimple *assign = last_and_only_stmt (middle_bb); + tree lhs, op0, op1, bound; + tree alt_lhs, alt_op0, alt_op1; + bool invert = false; + + if (!single_pred_p (middle_bb) + || !single_pred_p (alt_middle_bb)) + return false; + + if (!assign + || gimple_code (assign) != GIMPLE_ASSIGN) + return false; + + lhs = gimple_assign_lhs (assign); + ass_code = gimple_assign_rhs_code (assign); + if (ass_code != MAX_EXPR && ass_code != MIN_EXPR) + return false; + + op0 = gimple_assign_rhs1 (assign); + op1 = gimple_assign_rhs2 (assign); + + assign = last_and_only_stmt (alt_middle_bb); + if (!assign + || gimple_code (assign) != GIMPLE_ASSIGN) + return false; + + alt_lhs = gimple_assign_lhs (assign); + if (ass_code != gimple_assign_rhs_code (assign)) + return false; + + alt_op0 = gimple_assign_rhs1 (assign); + alt_op1 = gimple_assign_rhs2 (assign); + + if (!operand_equal_for_phi_arg_p (lhs, arg_true) + || !operand_equal_for_phi_arg_p (alt_lhs, arg_false)) + return false; + + if ((operand_equal_for_phi_arg_p (op0, smaller) + || (alt_smaller + && operand_equal_for_phi_arg_p (op0, alt_smaller))) + && (operand_equal_for_phi_arg_p (alt_op0, larger) + || (alt_larger + && operand_equal_for_phi_arg_p (alt_op0, alt_larger)))) + { + /* We got here if the condition is true, i.e., SMALLER < LARGER. */ + if (!operand_equal_for_phi_arg_p (op1, alt_op1)) + return false; + + if ((arg0 = strip_bit_not (op0)) != NULL + && (arg1 = strip_bit_not (alt_op0)) != NULL + && (bound = strip_bit_not (op1)) != NULL) + { + minmax = MAX_EXPR; + ass_code = invert_minmax_code (ass_code); + invert = true; + } + else + { + bound = op1; + minmax = MIN_EXPR; + arg0 = op0; + arg1 = alt_op0; + } + } + else if ((operand_equal_for_phi_arg_p (op0, larger) + || (alt_larger + && operand_equal_for_phi_arg_p (op0, alt_larger))) + && (operand_equal_for_phi_arg_p (alt_op0, smaller) + || (alt_smaller + && operand_equal_for_phi_arg_p (alt_op0, alt_smaller)))) + { + /* We got here if the condition is true, i.e., SMALLER > LARGER. */ + if (!operand_equal_for_phi_arg_p (op1, alt_op1)) + return false; + + if ((arg0 = strip_bit_not (op0)) != NULL + && (arg1 = strip_bit_not (alt_op0)) != NULL + && (bound = strip_bit_not (op1)) != NULL) + { + minmax = MIN_EXPR; + ass_code = invert_minmax_code (ass_code); + invert = true; + } + else + { + bound = op1; + minmax = MAX_EXPR; + arg0 = op0; + arg1 = alt_op0; + } + } + else + return false; + + /* Reset any range information from the basic block. */ + reset_flow_sensitive_info_in_bb (cond_bb); + + /* Emit the statement to compute min/max. */ + gimple_seq stmts = NULL; + tree phi_result = PHI_RESULT (phi); + result = gimple_build (&stmts, minmax, TREE_TYPE (phi_result), arg0, bound); + result = gimple_build (&stmts, ass_code, TREE_TYPE (phi_result), result, arg1); + if (invert) + result = gimple_build (&stmts, BIT_NOT_EXPR, TREE_TYPE (phi_result), result); + + gsi = gsi_last_bb (cond_bb); + gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT); + + replace_phi_edge_with_variable (cond_bb, e1, phi, result, false); + + return true; + } else { /* Recognize the following case, assuming d <= u: --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-3.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-phiopt" } */ + +#include + +uint8_t three_min (uint8_t xc, uint8_t xm, uint8_t xy) { + uint8_t xk; + if (xc < xm) { + xk = (uint8_t) (xc < xy ? xc : xy); + } else { + xk = (uint8_t) (xm < xy ? xm : xy); + } + return xk; +} + +/* { dg-final { scan-tree-dump-times "MIN_EXPR" 3 "phiopt1" } } */ +/* { dg-final { scan-tree-dump-times "MAX_EXPR" 0 "phiopt1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-4.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-4.c new file mode 100644 index 0000000000000000000000000000000000000000..0b6d667be868c2405eaefd17cb522da44bafa0e2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-4.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-phiopt" } */ + +#include + +uint8_t three_max (uint8_t xc, uint8_t xm, uint8_t xy) { + uint8_t xk; + if (xc > xm) { + xk = (uint8_t) (xc > xy ? xc : xy); + } else { + xk = (uint8_t) (xm > xy ? xm : xy); + } + return xk; +} + +/* { dg-final { scan-tree-dump-times "MIN_EXPR" 0 "phiopt1" } } */ +/* { dg-final { scan-tree-dump-times "MAX_EXPR" 3 "phiopt1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-5.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-5.c new file mode 100644 index 0000000000000000000000000000000000000000..650601a3cc75d09a9e6e54a35f5b9993074f8510 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-5.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-phiopt" } */ + +#include + +uint8_t three_minmax1 (uint8_t xc, uint8_t xm, uint8_t xy) { + uint8_t xk; + if (xc > xm) { + xk = (uint8_t) (xc < xy ? xc : xy); + } else { + xk = (uint8_t) (xm < xy ? xm : xy); + } + return xk; +} + +/* { dg-final { scan-tree-dump-times "MIN_EXPR" 2 "phiopt1" } } */ +/* { dg-final { scan-tree-dump-times "MAX_EXPR" 1 "phiopt1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-6.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-6.c new file mode 100644 index 0000000000000000000000000000000000000000..a628f6d99222958cfd8c410f0e85639e3a49dd4b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-6.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-phiopt" } */ + +#include + +uint8_t three_minmax3 (uint8_t xc, uint8_t xm, uint8_t xy) { + uint8_t xk; + if (xc > xm) { + xk = (uint8_t) (xy < xc ? xc : xy); + } else { + xk = (uint8_t) (xm < xy ? xm : xy); + } + return xk; +} + +/* { dg-final { scan-tree-dump-times "MIN_EXPR" 1 "phiopt1" } } */ +/* { dg-final { scan-tree-dump-times "MAX_EXPR" 1 "phiopt1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-7.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-7.c new file mode 100644 index 0000000000000000000000000000000000000000..cb42412c4ada433b2f59df0a8bef9fa7b1c5e104 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-7.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-phiopt" } */ + +#include + +uint8_t three_minmax2 (uint8_t xc, uint8_t xm, uint8_t xy) { + uint8_t xk; + if (xc > xm) { + xk = (uint8_t) (xc > xy ? xc : xy); + } else { + xk = (uint8_t) (xm < xy ? xm : xy); + } + return xk; +} +/* { dg-final { scan-tree-dump-times "MIN_EXPR" 1 "phiopt1" } } */ +/* { dg-final { scan-tree-dump-times "MAX_EXPR" 1 "phiopt1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-8.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-8.c new file mode 100644 index 0000000000000000000000000000000000000000..9cd050e932376bc50bd6ae60cb654fcab0bfdd1c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-8.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-phiopt" } */ + +#include + +uint8_t three_minmax11 (uint8_t xc, uint8_t xm, uint8_t xy) { + uint8_t xk; + if (xc < xm) { + xk = (uint8_t) (xc > xy ? xc : xy); + } else { + xk = (uint8_t) (xm > xy ? xm : xy); + } + return xk; +} + +/* { dg-final { scan-tree-dump-times "MIN_EXPR" 1 "phiopt1" } } */ +/* { dg-final { scan-tree-dump-times "MAX_EXPR" 2 "phiopt1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-1.c b/gcc/testsuite/gcc.dg/tree-ssa/split-path-1.c index 8b23ef4c7a3484cdc1647ee6d1b150f15685beff..902dde44a50e171b4f34ba7247d75a32d2c860ed 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/split-path-1.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-O2 -fsplit-paths -fdump-tree-split-paths-details --param max-jump-thread-duplication-stmts=20" } */ +/* { dg-options "-O2 -fsplit-paths -fdump-tree-split-paths-details --param max-jump-thread-duplication-stmts=20 -fno-ssa-phiopt" } */ #include #include diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc index 562468b7f02a9ffe2713318add551902c14f89c3..6246f054006ff16e73602e7ce2e367d2d21421b1 100644 --- a/gcc/tree-ssa-phiopt.cc +++ b/gcc/tree-ssa-phiopt.cc @@ -62,8 +62,8 @@ static gphi *factor_out_conditional_conversion (edge, edge, gphi *, tree, tree, gimple *); static int value_replacement (basic_block, basic_block, edge, edge, gphi *, tree, tree); -static bool minmax_replacement (basic_block, basic_block, - edge, edge, gphi *, tree, tree); +static bool minmax_replacement (basic_block, basic_block, basic_block, + edge, edge, gphi *, tree, tree, bool); static bool spaceship_replacement (basic_block, basic_block, edge, edge, gphi *, tree, tree); static bool cond_removal_in_builtin_zero_pattern (basic_block, basic_block, @@ -73,7 +73,7 @@ static bool cond_store_replacement (basic_block, basic_block, edge, edge, hash_set *); static bool cond_if_else_store_replacement (basic_block, basic_block, basic_block); static hash_set * get_non_trapping (); -static void replace_phi_edge_with_variable (basic_block, edge, gphi *, tree); +static void replace_phi_edge_with_variable (basic_block, edge, gphi *, tree, bool); static void hoist_adjacent_loads (basic_block, basic_block, basic_block, basic_block); static bool gate_hoist_loads (void); @@ -199,6 +199,7 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p) basic_block bb1, bb2; edge e1, e2; tree arg0, arg1; + bool diamond_minmax_p = false; bb = bb_order[i]; @@ -265,6 +266,29 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p) hoist_adjacent_loads (bb, bb1, bb2, bb3); continue; } + else if (EDGE_SUCC (bb1, 0)->dest == EDGE_SUCC (bb2, 0)->dest + && single_succ_p (bb1) + && single_succ_p (bb2) + && single_pred_p (bb1) + && single_pred_p (bb2) + && single_succ_p (EDGE_SUCC (bb1, 0)->dest)) + { + gimple_stmt_iterator it1 = gsi_start_nondebug_after_labels_bb (bb1); + gimple_stmt_iterator it2 = gsi_start_nondebug_after_labels_bb (bb2); + if (gsi_one_before_end_p (it1) && gsi_one_before_end_p (it2)) + { + gimple *stmt1 = gsi_stmt (it1); + gimple *stmt2 = gsi_stmt (it2); + if (is_gimple_assign (stmt1) && is_gimple_assign (stmt2)) + { + enum tree_code code1 = gimple_assign_rhs_code (stmt1); + enum tree_code code2 = gimple_assign_rhs_code (stmt2); + diamond_minmax_p + = (code1 == MIN_EXPR || code1 == MAX_EXPR) + && (code2 == MIN_EXPR || code2 == MAX_EXPR); + } + } + } else continue; @@ -316,6 +340,13 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p) if (!candorest) continue; + /* Check that we're looking for nested phis. */ + if (phis == NULL && diamond_minmax_p) + { + phis = phi_nodes (EDGE_SUCC (bb2, 0)->dest); + e2 = EDGE_SUCC (bb2, 0); + } + phi = single_non_singleton_phi_for_edges (phis, e1, e2); if (!phi) continue; @@ -329,6 +360,7 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p) gphi *newphi; if (single_pred_p (bb1) + && !diamond_minmax_p && (newphi = factor_out_conditional_conversion (e1, e2, phi, arg0, arg1, cond_stmt))) @@ -343,20 +375,25 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p) } /* Do the replacement of conditional if it can be done. */ - if (!early_p && two_value_replacement (bb, bb1, e2, phi, arg0, arg1)) + if (!early_p + && !diamond_minmax_p + && two_value_replacement (bb, bb1, e2, phi, arg0, arg1)) cfgchanged = true; - else if (match_simplify_replacement (bb, bb1, e1, e2, phi, - arg0, arg1, - early_p)) + else if (!diamond_minmax_p + && match_simplify_replacement (bb, bb1, e1, e2, phi, + arg0, arg1, early_p)) cfgchanged = true; else if (!early_p + && !diamond_minmax_p && single_pred_p (bb1) && cond_removal_in_builtin_zero_pattern (bb, bb1, e1, e2, phi, arg0, arg1)) cfgchanged = true; - else if (minmax_replacement (bb, bb1, e1, e2, phi, arg0, arg1)) + else if (minmax_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1, + diamond_minmax_p)) cfgchanged = true; else if (single_pred_p (bb1) + && !diamond_minmax_p && spaceship_replacement (bb, bb1, e1, e2, phi, arg0, arg1)) cfgchanged = true; } @@ -385,7 +422,7 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p) static void replace_phi_edge_with_variable (basic_block cond_block, - edge e, gphi *phi, tree new_tree) + edge e, gphi *phi, tree new_tree, bool delete_bb = true) { basic_block bb = gimple_bb (phi); gimple_stmt_iterator gsi; @@ -428,7 +465,7 @@ replace_phi_edge_with_variable (basic_block cond_block, edge_to_remove = EDGE_SUCC (cond_block, 1); else edge_to_remove = EDGE_SUCC (cond_block, 0); - if (EDGE_COUNT (edge_to_remove->dest->preds) == 1) + if (EDGE_COUNT (edge_to_remove->dest->preds) == 1 && delete_bb) { e->flags |= EDGE_FALLTHRU; e->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE); @@ -1564,15 +1601,52 @@ value_replacement (basic_block cond_bb, basic_block middle_bb, return 0; } +/* If VAR is an SSA_NAME that points to a BIT_NOT_EXPR then return the TREE for + the value being inverted. */ + +static tree +strip_bit_not (tree var) +{ + if (TREE_CODE (var) != SSA_NAME) + return NULL_TREE; + + gimple *assign = SSA_NAME_DEF_STMT (var); + if (gimple_code (assign) != GIMPLE_ASSIGN) + return NULL_TREE; + + if (gimple_assign_rhs_code (assign) != BIT_NOT_EXPR) + return NULL_TREE; + + return gimple_assign_rhs1 (assign); +} + +/* Invert a MIN to a MAX or a MAX to a MIN expression CODE. */ + +enum tree_code +invert_minmax_code (enum tree_code code) +{ + switch (code) { + case MIN_EXPR: + return MAX_EXPR; + case MAX_EXPR: + return MIN_EXPR; + default: + gcc_unreachable (); + } +} + /* The function minmax_replacement does the main work of doing the minmax replacement. Return true if the replacement is done. Otherwise return false. BB is the basic block where the replacement is going to be done on. ARG0 - is argument 0 from the PHI. Likewise for ARG1. */ + is argument 0 from the PHI. Likewise for ARG1. + + If THREEWAY_P then expect the BB to be laid out in diamond shape with each + BB containing only a MIN or MAX expression. */ static bool -minmax_replacement (basic_block cond_bb, basic_block middle_bb, - edge e0, edge e1, gphi *phi, tree arg0, tree arg1) +minmax_replacement (basic_block cond_bb, basic_block middle_bb, basic_block alt_middle_bb, + edge e0, edge e1, gphi *phi, tree arg0, tree arg1, bool threeway_p) { tree result; edge true_edge, false_edge; @@ -1727,9 +1801,14 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, if (false_edge->dest == middle_bb) false_edge = EDGE_SUCC (false_edge->dest, 0); + /* When THREEWAY_P then e1 will point to the edge of the final transition + from middle-bb to end. */ if (true_edge == e0) { - gcc_assert (false_edge == e1); + if (threeway_p) + gcc_assert (false_edge == EDGE_PRED (e1->src, 0)); + else + gcc_assert (false_edge == e1); arg_true = arg0; arg_false = arg1; } @@ -1768,6 +1847,133 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, else return false; } + else if (middle_bb != alt_middle_bb && threeway_p) + { + /* Recognize the following case: + + if (smaller < larger) + a = MIN (smaller, c); + else + b = MIN (larger, c); + x = PHI + + This is equivalent to + + a = MIN (smaller, c); + x = MIN (larger, a); */ + + gimple *assign = last_and_only_stmt (middle_bb); + tree lhs, op0, op1, bound; + tree alt_lhs, alt_op0, alt_op1; + bool invert = false; + + if (!single_pred_p (middle_bb) + || !single_pred_p (alt_middle_bb)) + return false; + + if (!assign + || gimple_code (assign) != GIMPLE_ASSIGN) + return false; + + lhs = gimple_assign_lhs (assign); + ass_code = gimple_assign_rhs_code (assign); + if (ass_code != MAX_EXPR && ass_code != MIN_EXPR) + return false; + + op0 = gimple_assign_rhs1 (assign); + op1 = gimple_assign_rhs2 (assign); + + assign = last_and_only_stmt (alt_middle_bb); + if (!assign + || gimple_code (assign) != GIMPLE_ASSIGN) + return false; + + alt_lhs = gimple_assign_lhs (assign); + if (ass_code != gimple_assign_rhs_code (assign)) + return false; + + alt_op0 = gimple_assign_rhs1 (assign); + alt_op1 = gimple_assign_rhs2 (assign); + + if (!operand_equal_for_phi_arg_p (lhs, arg_true) + || !operand_equal_for_phi_arg_p (alt_lhs, arg_false)) + return false; + + if ((operand_equal_for_phi_arg_p (op0, smaller) + || (alt_smaller + && operand_equal_for_phi_arg_p (op0, alt_smaller))) + && (operand_equal_for_phi_arg_p (alt_op0, larger) + || (alt_larger + && operand_equal_for_phi_arg_p (alt_op0, alt_larger)))) + { + /* We got here if the condition is true, i.e., SMALLER < LARGER. */ + if (!operand_equal_for_phi_arg_p (op1, alt_op1)) + return false; + + if ((arg0 = strip_bit_not (op0)) != NULL + && (arg1 = strip_bit_not (alt_op0)) != NULL + && (bound = strip_bit_not (op1)) != NULL) + { + minmax = MAX_EXPR; + ass_code = invert_minmax_code (ass_code); + invert = true; + } + else + { + bound = op1; + minmax = MIN_EXPR; + arg0 = op0; + arg1 = alt_op0; + } + } + else if ((operand_equal_for_phi_arg_p (op0, larger) + || (alt_larger + && operand_equal_for_phi_arg_p (op0, alt_larger))) + && (operand_equal_for_phi_arg_p (alt_op0, smaller) + || (alt_smaller + && operand_equal_for_phi_arg_p (alt_op0, alt_smaller)))) + { + /* We got here if the condition is true, i.e., SMALLER > LARGER. */ + if (!operand_equal_for_phi_arg_p (op1, alt_op1)) + return false; + + if ((arg0 = strip_bit_not (op0)) != NULL + && (arg1 = strip_bit_not (alt_op0)) != NULL + && (bound = strip_bit_not (op1)) != NULL) + { + minmax = MIN_EXPR; + ass_code = invert_minmax_code (ass_code); + invert = true; + } + else + { + bound = op1; + minmax = MAX_EXPR; + arg0 = op0; + arg1 = alt_op0; + } + } + else + return false; + + /* Reset any range information from the basic block. */ + reset_flow_sensitive_info_in_bb (cond_bb); + + /* Emit the statement to compute min/max. */ + gimple_seq stmts = NULL; + tree phi_result = PHI_RESULT (phi); + result = gimple_build (&stmts, minmax, TREE_TYPE (phi_result), arg0, bound); + result = gimple_build (&stmts, ass_code, TREE_TYPE (phi_result), result, arg1); + if (invert) + result = gimple_build (&stmts, BIT_NOT_EXPR, TREE_TYPE (phi_result), result); + + gsi = gsi_last_bb (cond_bb); + gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT); + + replace_phi_edge_with_variable (cond_bb, e1, phi, result, false); + + return true; + } else { /* Recognize the following case, assuming d <= u: