From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-he1eur04on2058.outbound.protection.outlook.com [40.107.7.58]) by sourceware.org (Postfix) with ESMTPS id 4276E3858C2F for ; Mon, 27 Feb 2023 12:33:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4276E3858C2F Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=goaQRdebHoCkEtN0fpbQSZhBpfQ2tAnyPkBNN3cew1M=; b=9MqX+7jNTOxohYUvcVQKdJedXCR+p5uSMKapILRWU+bprLkQ+9Ao+nyL+Tj6xhChJTNcx8Qo/c6kCeRFNv72Pinroxm0ARtCQ6Ls+G5Q/541z5KDr0M4nyVNuq83xUCZR+HhRj5Y3t3qQMX1lXp9vyI/mg7C5NwP8K3AooJBfuE= Received: from AM5PR0402CA0023.eurprd04.prod.outlook.com (2603:10a6:203:90::33) by AS8PR08MB6120.eurprd08.prod.outlook.com (2603:10a6:20b:299::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6134.27; Mon, 27 Feb 2023 12:33:36 +0000 Received: from AM7EUR03FT027.eop-EUR03.prod.protection.outlook.com (2603:10a6:203:90:cafe::e9) by AM5PR0402CA0023.outlook.office365.com (2603:10a6:203:90::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6134.25 via Frontend Transport; Mon, 27 Feb 2023 12:33:36 +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 AM7EUR03FT027.mail.protection.outlook.com (100.127.140.124) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6156.12 via Frontend Transport; Mon, 27 Feb 2023 12:33:36 +0000 Received: ("Tessian outbound 0d7b2ab0f13d:v132"); Mon, 27 Feb 2023 12:33:36 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: fc8b4759ad4514ad X-CR-MTA-TID: 64aa7808 Received: from ecc813ec87dd.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id 094424E8-9DA0-460D-B50A-050066160A06.1; Mon, 27 Feb 2023 12:33:28 +0000 Received: from EUR04-HE1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id ecc813ec87dd.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Mon, 27 Feb 2023 12:33:28 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=agLi/SqgfUmLIOQotgz/qUsE0wSMgLb1taj/7pNzy1WX7uAt/km+TRjMAPa6rRot7A4FfUPKwqI0s7itpn0OutyGp/No8H/CtACfp6h81bGdu4RvanKD2j15OXQPANIJ84bXVHd2v+R4wK/l4QmSwAuKeOkiFIEzHZ1yiC6MZGGZkT2zsBIppy4UEbRZqGKvmW90NXjmSlxsR/JQ2nWWxGTFQvva1GIXnOIFYiK9N5YtdFiMf8M4gfOk0rFi5qavz8d/TjbdJRd9hw+9ovOk9RjCD8p2XS3Ds5L2tQdL4/bqG22Gm3rmhZuuJxxsF4Nm7dPweX5R2ptpIbfE1ZPkfw== 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=goaQRdebHoCkEtN0fpbQSZhBpfQ2tAnyPkBNN3cew1M=; b=JelS1p2XoiqgvXlGhq5z8qM0GauI8JAyhswh68L5TQ43QZ09g9vE0YjjPpM3+Mk3EER/ENQcoufvPbRUEyDrQPOYHTGcg0jTOShl8jBNNXkHFldZT650Mxk9fENrb3orvpja1SG4R9JYQufZYMZk2j0hlioCnmM/nmVzpp8mkQr2j17N2vPEuZcAC+/nDPPa/rPY1Ewpyn1ExZdmyvaLNmyNKD2adrcKuYP6lv5PT/0tIywi9h4GZE9t75NcbUC3/xq9wrWAJpv6J/forY3Z7YN3ULe3jfrPyGlYshAw7U+WTReZ5TxiMBj6nKCTp3TRCNa3TN/r8VVtiBgcyxDkGA== 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=goaQRdebHoCkEtN0fpbQSZhBpfQ2tAnyPkBNN3cew1M=; b=9MqX+7jNTOxohYUvcVQKdJedXCR+p5uSMKapILRWU+bprLkQ+9Ao+nyL+Tj6xhChJTNcx8Qo/c6kCeRFNv72Pinroxm0ARtCQ6Ls+G5Q/541z5KDr0M4nyVNuq83xUCZR+HhRj5Y3t3qQMX1lXp9vyI/mg7C5NwP8K3AooJBfuE= 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 AS8PR08MB6006.eurprd08.prod.outlook.com (2603:10a6:20b:29a::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6134.29; Mon, 27 Feb 2023 12:33:26 +0000 Received: from VI1PR08MB5325.eurprd08.prod.outlook.com ([fe80::210c:d369:23f7:84fe]) by VI1PR08MB5325.eurprd08.prod.outlook.com ([fe80::210c:d369:23f7:84fe%6]) with mapi id 15.20.6134.027; Mon, 27 Feb 2023 12:33:25 +0000 Date: Mon, 27 Feb 2023 12:33:18 +0000 From: Tamar Christina To: gcc-patches@gcc.gnu.org Cc: nd@arm.com, amacleod@redhat.com, aldyh@redhat.com Subject: [PATCH 2/4][ranger]: Add range-ops for widen addition and widen multiplication [PR108583] Message-ID: Content-Type: multipart/mixed; boundary="N35aayhT7igGlY7K" Content-Disposition: inline In-Reply-To: X-ClientProxiedBy: SA1PR05CA0011.namprd05.prod.outlook.com (2603:10b6:806:2d2::13) To VI1PR08MB5325.eurprd08.prod.outlook.com (2603:10a6:803:13e::17) MIME-Version: 1.0 X-MS-TrafficTypeDiagnostic: VI1PR08MB5325:EE_|AS8PR08MB6006:EE_|AM7EUR03FT027:EE_|AS8PR08MB6120:EE_ X-MS-Office365-Filtering-Correlation-Id: e2bb83a6-2df8-46e3-6fd1-08db18bed8d2 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: XXiAmgWNwMyeKJAPxjzjsyadZboG3jTbftjNmAW9gRo66cFFWvSZbj7TzdIl5cMiB/M6GAaG07ydepax+PP2DDgYhrbT725qGpLB6Ov1bo41BW3BQxyR/dwPi2MFrdRSLuGEA+RnqqJJ1Zi0wHMGXViPMxm9Th7ByUTIjxPXneRsXTpGM5ZZEmGocggBvZFVlVGIjukknFe08z5S23PO2fX4GhN7q0ngVs0IrijcnFwmoKbA+/dwcx6anuhMzvtFjcAHAHDyNDb3ht3OEuE3k3QZMmx5Qt2VKSXsCfsMnm8lmSc08Vm2/koYWdUfK7g3WfH7v8936x9zaXiBIhPus0IIxoCr/S+HG8125AmYStmzN1OEbcGkPMf4oQMN0cZ/HbX9qznd9mj7Ev7o9XZ2988wwGzEFJXHJrbydl7pCNOsqk+rQ1YQ/ODAwsG/k75aDnnl5sxg4AFWuWsrKucy/iR6dpwIlAJkhD//dcii/reaZ6bjz3qKhdhuugIOq2I8XJykv/yhXavGS207jj8TGsqM4wKh2a+3M6Sy8UYPkhEYcMGLwjNYR6dnWQNtfgnGpD2qdxBTZIcTQsfy3Z9+BZuoinwr8ZnRkytdkZnUT8WQvRKrsV9c+zrlyxhFz8ZqSD+oy+ZnNMspGz2U1EGz/a7+uBW6IrRFYN5c6RQfzFf+JSG5Eo6lKUMWdfgruWseIQstQ+JL7oyK9yO0LHtfIw== 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:(13230025)(4636009)(376002)(366004)(396003)(136003)(346002)(39850400004)(451199018)(316002)(2906002)(36756003)(5660300002)(235185007)(44832011)(8936002)(86362001)(6512007)(33964004)(6506007)(44144004)(66946007)(8676002)(186003)(38100700002)(26005)(4743002)(4326008)(6916009)(66556008)(66476007)(41300700001)(2616005)(478600001)(6486002)(6666004)(2700100001);DIR:OUT;SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS8PR08MB6006 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: AM7EUR03FT027.eop-EUR03.prod.protection.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: 94e928ba-6d27-4656-1d64-08db18bed279 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 40gCLa60PYUnifYsCUQHLsU3egTcXXR6U5Og9gbY9y8Kz2d9xpDgfrJnXruHZ8oEK9oE1FJL25nvLr1HmlsgMgaieUAt2vnY03wrqdTiekQYvsu2pN2iqnalnMvCtJkNBS65+RdAd4bp9zXa58fa7TW7HvdzX2hhj1sMZTnKvagHhxKiUVpl0lhjPRIDubWCw9+xdLXC1eL/BJ2X8Jc8qYW+kGklstHACYz58lIrx+B7bqgj8WH+ZDjxddy+O+iTfNbJgUBCL1sGUH3FqqRf7U0I11ZG8RqQgGFMvH4/DrMqJcv0lIxY1a1jy6J9QyBeWHsNQxHJLhrxCAFHgkw3NjwqbLsdpCvo11pGQiEYZWcpKjngfUw/+NsdpA13gaO0ZcRjToMFnWaPYxNZ7qhlnou/SfqtG4o6KkbtY8EsXpbr57kkwqC/rGay/Le2JpXCJz80irJTnMTDkqxQEPoAnIpdtEE4N1Tx5/fhu0yPilfS+tkoIprPNlyi6DU1UvmiZNZ8yk0ZBYTSh+es8GEa5wRvQa+xl4+SlTwgdO0MN/NXR48qgazYB1s9xA5VKuG3HKauF5d9HxPaoUsbyeKDpzvNDy62CkpbiPUaySzxA3bUtxhjRZ4XEbvrAQvSRwAZNmZ6YdlgG/IHa6JCgOMOt9p5fSQteoyJAdeSJ6U9QBCNfOJBy0nQx6nbr0z8DB5MLBkN/YIW89XuPXHOOdxDDg5x8bkoVkigQx4tR2RMb64= 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:(13230025)(4636009)(39860400002)(136003)(396003)(346002)(376002)(451199018)(40470700004)(46966006)(36840700001)(8676002)(86362001)(6506007)(6666004)(107886003)(36756003)(40460700003)(36860700001)(82740400003)(8936002)(235185007)(81166007)(47076005)(82310400005)(356005)(5660300002)(40480700001)(478600001)(4743002)(336012)(2616005)(186003)(26005)(44144004)(33964004)(6486002)(6916009)(70206006)(4326008)(2906002)(44832011)(70586007)(316002)(41300700001)(6512007)(2700100001);DIR:OUT;SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Feb 2023 12:33:36.2798 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: e2bb83a6-2df8-46e3-6fd1-08db18bed8d2 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: AM7EUR03FT027.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS8PR08MB6120 X-Spam-Status: No, score=-11.6 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,RCVD_IN_VALIDITY_RPBL,SPF_HELO_PASS,SPF_NONE,TXREP,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 List-Id: --N35aayhT7igGlY7K Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Hi All, This adds range-ops for widening addition and widening multiplication. I couldn't figure out how to write a test for this. It looks like there are self tests but not a way to write standalone ones? I did create testcases in the patch 3/4 which tests the end result. Bootstrapped Regtested on aarch64-none-linux-gnu and no issues. Ok for master? Thanks, Tamar gcc/ChangeLog: PR target/108583 * gimple-range-op.h (gimple_range_op_handler): Add maybe_non_standard. * gimple-range-op.cc (gimple_range_op_handler::gimple_range_op_handler): Use it. (gimple_range_op_handler::maybe_non_standard): New. * range-op.cc (class operator_widen_plus_signed, operator_widen_plus_signed::wi_fold, class operator_widen_plus_unsigned, operator_widen_plus_unsigned::wi_fold, class operator_widen_mult_signed, operator_widen_mult_signed::wi_fold, class operator_widen_mult_unsigned, operator_widen_mult_unsigned::wi_fold, ptr_op_widen_mult_signed, ptr_op_widen_mult_unsigned, ptr_op_widen_plus_signed, ptr_op_widen_plus_unsigned): New. * range-op.h (ptr_op_widen_mult_signed, ptr_op_widen_mult_unsigned, ptr_op_widen_plus_signed, ptr_op_widen_plus_unsigned): New Co-Authored-By: Andrew MacLeod --- inline copy of patch -- diff --git a/gcc/gimple-range-op.h b/gcc/gimple-range-op.h index 743b858126e333ea9590c0f175aacb476260c048..1bf63c5ce6f5db924a1f5907ab4539e376281bd0 100644 --- a/gcc/gimple-range-op.h +++ b/gcc/gimple-range-op.h @@ -41,6 +41,7 @@ public: relation_trio = TRIO_VARYING); private: void maybe_builtin_call (); + void maybe_non_standard (); gimple *m_stmt; tree m_op1, m_op2; }; diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc index d9dfdc56939bb62ade72726b15c3d5e87e4ddcd1..ad13c873c6303db5b68b74db1562c0db6763101f 100644 --- a/gcc/gimple-range-op.cc +++ b/gcc/gimple-range-op.cc @@ -179,6 +179,8 @@ gimple_range_op_handler::gimple_range_op_handler (gimple *s) // statements. if (is_a (m_stmt)) maybe_builtin_call (); + else + maybe_non_standard (); } // Calculate what we can determine of the range of this unary @@ -764,6 +766,44 @@ public: } } op_cfn_parity; +// Set up a gimple_range_op_handler for any nonstandard function which can be +// supported via range-ops. + +void +gimple_range_op_handler::maybe_non_standard () +{ + range_operator *signed_op = ptr_op_widen_mult_signed; + range_operator *unsigned_op = ptr_op_widen_mult_unsigned; + if (gimple_code (m_stmt) == GIMPLE_ASSIGN) + switch (gimple_assign_rhs_code (m_stmt)) + { + case WIDEN_PLUS_EXPR: + { + signed_op = ptr_op_widen_plus_signed; + unsigned_op = ptr_op_widen_plus_unsigned; + } + gcc_fallthrough (); + case WIDEN_MULT_EXPR: + { + m_valid = true; + m_op1 = gimple_assign_rhs1 (m_stmt); + m_op2 = gimple_assign_rhs2 (m_stmt); + bool signed1 = TYPE_SIGN (TREE_TYPE (m_op1)) == SIGNED; + bool signed2 = TYPE_SIGN (TREE_TYPE (m_op2)) == SIGNED; + if (signed2 && !signed1) + std::swap (m_op1, m_op2); + + if (signed1 || signed2) + m_int = signed_op; + else + m_int = unsigned_op; + break; + } + default: + break; + } +} + // Set up a gimple_range_op_handler for any built in function which can be // supported via range-ops. diff --git a/gcc/range-op.h b/gcc/range-op.h index f00b747f08a1fa8404c63bfe5a931b4048008b03..b1eeac70df81f2bdf228af7adff5399e7ac5e5d6 100644 --- a/gcc/range-op.h +++ b/gcc/range-op.h @@ -311,4 +311,8 @@ private: // This holds the range op table for floating point operations. extern floating_op_table *floating_tree_table; +extern range_operator *ptr_op_widen_mult_signed; +extern range_operator *ptr_op_widen_mult_unsigned; +extern range_operator *ptr_op_widen_plus_signed; +extern range_operator *ptr_op_widen_plus_unsigned; #endif // GCC_RANGE_OP_H diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 5c67bce6d3aab81ad3186b902e09d6a96878d9bb..718ccb6f074e1a2a9ef1b7a5d4e879898d4a7fc3 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -1556,6 +1556,73 @@ operator_plus::op2_range (irange &r, tree type, return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ()); } +class operator_widen_plus_signed : public range_operator +{ +public: + virtual void wi_fold (irange &r, tree type, + const wide_int &lh_lb, + const wide_int &lh_ub, + const wide_int &rh_lb, + const wide_int &rh_ub) const; +} op_widen_plus_signed; +range_operator *ptr_op_widen_plus_signed = &op_widen_plus_signed; + +void +operator_widen_plus_signed::wi_fold (irange &r, tree type, + const wide_int &lh_lb, + const wide_int &lh_ub, + const wide_int &rh_lb, + const wide_int &rh_ub) const +{ + wi::overflow_type ov_lb, ov_ub; + signop s = TYPE_SIGN (type); + + wide_int lh_wlb + = wide_int::from (lh_lb, wi::get_precision (lh_lb) * 2, SIGNED); + wide_int lh_wub + = wide_int::from (lh_ub, wi::get_precision (lh_ub) * 2, SIGNED); + wide_int rh_wlb = wide_int::from (rh_lb, wi::get_precision (rh_lb) * 2, s); + wide_int rh_wub = wide_int::from (rh_ub, wi::get_precision (rh_ub) * 2, s); + + wide_int new_lb = wi::add (lh_wlb, rh_wlb, s, &ov_lb); + wide_int new_ub = wi::add (lh_wub, rh_wub, s, &ov_ub); + + r = int_range<2> (type, new_lb, new_ub); +} + +class operator_widen_plus_unsigned : public range_operator +{ +public: + virtual void wi_fold (irange &r, tree type, + const wide_int &lh_lb, + const wide_int &lh_ub, + const wide_int &rh_lb, + const wide_int &rh_ub) const; +} op_widen_plus_unsigned; +range_operator *ptr_op_widen_plus_unsigned = &op_widen_plus_unsigned; + +void +operator_widen_plus_unsigned::wi_fold (irange &r, tree type, + const wide_int &lh_lb, + const wide_int &lh_ub, + const wide_int &rh_lb, + const wide_int &rh_ub) const +{ + wi::overflow_type ov_lb, ov_ub; + signop s = TYPE_SIGN (type); + + wide_int lh_wlb + = wide_int::from (lh_lb, wi::get_precision (lh_lb) * 2, UNSIGNED); + wide_int lh_wub + = wide_int::from (lh_ub, wi::get_precision (lh_ub) * 2, UNSIGNED); + wide_int rh_wlb = wide_int::from (rh_lb, wi::get_precision (rh_lb) * 2, s); + wide_int rh_wub = wide_int::from (rh_ub, wi::get_precision (rh_ub) * 2, s); + + wide_int new_lb = wi::add (lh_wlb, rh_wlb, s, &ov_lb); + wide_int new_ub = wi::add (lh_wub, rh_wub, s, &ov_ub); + + r = int_range<2> (type, new_lb, new_ub); +} class operator_minus : public range_operator { @@ -2031,6 +2098,70 @@ operator_mult::wi_fold (irange &r, tree type, } } +class operator_widen_mult_signed : public range_operator +{ +public: + virtual void wi_fold (irange &r, tree type, + const wide_int &lh_lb, + const wide_int &lh_ub, + const wide_int &rh_lb, + const wide_int &rh_ub) + const; +} op_widen_mult_signed; +range_operator *ptr_op_widen_mult_signed = &op_widen_mult_signed; + +void +operator_widen_mult_signed::wi_fold (irange &r, tree type, + const wide_int &lh_lb, + const wide_int &lh_ub, + const wide_int &rh_lb, + const wide_int &rh_ub) const +{ + signop s = TYPE_SIGN (type); + + wide_int lh_wlb = wide_int::from (lh_lb, wi::get_precision (lh_lb) * 2, SIGNED); + wide_int lh_wub = wide_int::from (lh_ub, wi::get_precision (lh_ub) * 2, SIGNED); + wide_int rh_wlb = wide_int::from (rh_lb, wi::get_precision (rh_lb) * 2, s); + wide_int rh_wub = wide_int::from (rh_ub, wi::get_precision (rh_ub) * 2, s); + + /* We don't expect a widening multiplication to be able to overflow but range + calculations for multiplications are complicated. After widening the + operands lets call the base class. */ + return op_mult.wi_fold (r, type, lh_wlb, lh_wub, rh_wlb, rh_wub); +} + + +class operator_widen_mult_unsigned : public range_operator +{ +public: + virtual void wi_fold (irange &r, tree type, + const wide_int &lh_lb, + const wide_int &lh_ub, + const wide_int &rh_lb, + const wide_int &rh_ub) + const; +} op_widen_mult_unsigned; +range_operator *ptr_op_widen_mult_unsigned = &op_widen_mult_unsigned; + +void +operator_widen_mult_unsigned::wi_fold (irange &r, tree type, + const wide_int &lh_lb, + const wide_int &lh_ub, + const wide_int &rh_lb, + const wide_int &rh_ub) const +{ + signop s = TYPE_SIGN (type); + + wide_int lh_wlb = wide_int::from (lh_lb, wi::get_precision (lh_lb) * 2, UNSIGNED); + wide_int lh_wub = wide_int::from (lh_ub, wi::get_precision (lh_ub) * 2, UNSIGNED); + wide_int rh_wlb = wide_int::from (rh_lb, wi::get_precision (rh_lb) * 2, s); + wide_int rh_wub = wide_int::from (rh_ub, wi::get_precision (rh_ub) * 2, s); + + /* We don't expect a widening multiplication to be able to overflow but range + calculations for multiplications are complicated. After widening the + operands lets call the base class. */ + return op_mult.wi_fold (r, type, lh_wlb, lh_wub, rh_wlb, rh_wub); +} class operator_div : public cross_product_operator { -- --N35aayhT7igGlY7K Content-Type: text/plain; charset=utf-8 Content-Disposition: attachment; filename="rb16929.patch" diff --git a/gcc/gimple-range-op.h b/gcc/gimple-range-op.h index 743b858126e333ea9590c0f175aacb476260c048..1bf63c5ce6f5db924a1f5907ab4539e376281bd0 100644 --- a/gcc/gimple-range-op.h +++ b/gcc/gimple-range-op.h @@ -41,6 +41,7 @@ public: relation_trio = TRIO_VARYING); private: void maybe_builtin_call (); + void maybe_non_standard (); gimple *m_stmt; tree m_op1, m_op2; }; diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc index d9dfdc56939bb62ade72726b15c3d5e87e4ddcd1..ad13c873c6303db5b68b74db1562c0db6763101f 100644 --- a/gcc/gimple-range-op.cc +++ b/gcc/gimple-range-op.cc @@ -179,6 +179,8 @@ gimple_range_op_handler::gimple_range_op_handler (gimple *s) // statements. if (is_a (m_stmt)) maybe_builtin_call (); + else + maybe_non_standard (); } // Calculate what we can determine of the range of this unary @@ -764,6 +766,44 @@ public: } } op_cfn_parity; +// Set up a gimple_range_op_handler for any nonstandard function which can be +// supported via range-ops. + +void +gimple_range_op_handler::maybe_non_standard () +{ + range_operator *signed_op = ptr_op_widen_mult_signed; + range_operator *unsigned_op = ptr_op_widen_mult_unsigned; + if (gimple_code (m_stmt) == GIMPLE_ASSIGN) + switch (gimple_assign_rhs_code (m_stmt)) + { + case WIDEN_PLUS_EXPR: + { + signed_op = ptr_op_widen_plus_signed; + unsigned_op = ptr_op_widen_plus_unsigned; + } + gcc_fallthrough (); + case WIDEN_MULT_EXPR: + { + m_valid = true; + m_op1 = gimple_assign_rhs1 (m_stmt); + m_op2 = gimple_assign_rhs2 (m_stmt); + bool signed1 = TYPE_SIGN (TREE_TYPE (m_op1)) == SIGNED; + bool signed2 = TYPE_SIGN (TREE_TYPE (m_op2)) == SIGNED; + if (signed2 && !signed1) + std::swap (m_op1, m_op2); + + if (signed1 || signed2) + m_int = signed_op; + else + m_int = unsigned_op; + break; + } + default: + break; + } +} + // Set up a gimple_range_op_handler for any built in function which can be // supported via range-ops. diff --git a/gcc/range-op.h b/gcc/range-op.h index f00b747f08a1fa8404c63bfe5a931b4048008b03..b1eeac70df81f2bdf228af7adff5399e7ac5e5d6 100644 --- a/gcc/range-op.h +++ b/gcc/range-op.h @@ -311,4 +311,8 @@ private: // This holds the range op table for floating point operations. extern floating_op_table *floating_tree_table; +extern range_operator *ptr_op_widen_mult_signed; +extern range_operator *ptr_op_widen_mult_unsigned; +extern range_operator *ptr_op_widen_plus_signed; +extern range_operator *ptr_op_widen_plus_unsigned; #endif // GCC_RANGE_OP_H diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 5c67bce6d3aab81ad3186b902e09d6a96878d9bb..718ccb6f074e1a2a9ef1b7a5d4e879898d4a7fc3 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -1556,6 +1556,73 @@ operator_plus::op2_range (irange &r, tree type, return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ()); } +class operator_widen_plus_signed : public range_operator +{ +public: + virtual void wi_fold (irange &r, tree type, + const wide_int &lh_lb, + const wide_int &lh_ub, + const wide_int &rh_lb, + const wide_int &rh_ub) const; +} op_widen_plus_signed; +range_operator *ptr_op_widen_plus_signed = &op_widen_plus_signed; + +void +operator_widen_plus_signed::wi_fold (irange &r, tree type, + const wide_int &lh_lb, + const wide_int &lh_ub, + const wide_int &rh_lb, + const wide_int &rh_ub) const +{ + wi::overflow_type ov_lb, ov_ub; + signop s = TYPE_SIGN (type); + + wide_int lh_wlb + = wide_int::from (lh_lb, wi::get_precision (lh_lb) * 2, SIGNED); + wide_int lh_wub + = wide_int::from (lh_ub, wi::get_precision (lh_ub) * 2, SIGNED); + wide_int rh_wlb = wide_int::from (rh_lb, wi::get_precision (rh_lb) * 2, s); + wide_int rh_wub = wide_int::from (rh_ub, wi::get_precision (rh_ub) * 2, s); + + wide_int new_lb = wi::add (lh_wlb, rh_wlb, s, &ov_lb); + wide_int new_ub = wi::add (lh_wub, rh_wub, s, &ov_ub); + + r = int_range<2> (type, new_lb, new_ub); +} + +class operator_widen_plus_unsigned : public range_operator +{ +public: + virtual void wi_fold (irange &r, tree type, + const wide_int &lh_lb, + const wide_int &lh_ub, + const wide_int &rh_lb, + const wide_int &rh_ub) const; +} op_widen_plus_unsigned; +range_operator *ptr_op_widen_plus_unsigned = &op_widen_plus_unsigned; + +void +operator_widen_plus_unsigned::wi_fold (irange &r, tree type, + const wide_int &lh_lb, + const wide_int &lh_ub, + const wide_int &rh_lb, + const wide_int &rh_ub) const +{ + wi::overflow_type ov_lb, ov_ub; + signop s = TYPE_SIGN (type); + + wide_int lh_wlb + = wide_int::from (lh_lb, wi::get_precision (lh_lb) * 2, UNSIGNED); + wide_int lh_wub + = wide_int::from (lh_ub, wi::get_precision (lh_ub) * 2, UNSIGNED); + wide_int rh_wlb = wide_int::from (rh_lb, wi::get_precision (rh_lb) * 2, s); + wide_int rh_wub = wide_int::from (rh_ub, wi::get_precision (rh_ub) * 2, s); + + wide_int new_lb = wi::add (lh_wlb, rh_wlb, s, &ov_lb); + wide_int new_ub = wi::add (lh_wub, rh_wub, s, &ov_ub); + + r = int_range<2> (type, new_lb, new_ub); +} class operator_minus : public range_operator { @@ -2031,6 +2098,70 @@ operator_mult::wi_fold (irange &r, tree type, } } +class operator_widen_mult_signed : public range_operator +{ +public: + virtual void wi_fold (irange &r, tree type, + const wide_int &lh_lb, + const wide_int &lh_ub, + const wide_int &rh_lb, + const wide_int &rh_ub) + const; +} op_widen_mult_signed; +range_operator *ptr_op_widen_mult_signed = &op_widen_mult_signed; + +void +operator_widen_mult_signed::wi_fold (irange &r, tree type, + const wide_int &lh_lb, + const wide_int &lh_ub, + const wide_int &rh_lb, + const wide_int &rh_ub) const +{ + signop s = TYPE_SIGN (type); + + wide_int lh_wlb = wide_int::from (lh_lb, wi::get_precision (lh_lb) * 2, SIGNED); + wide_int lh_wub = wide_int::from (lh_ub, wi::get_precision (lh_ub) * 2, SIGNED); + wide_int rh_wlb = wide_int::from (rh_lb, wi::get_precision (rh_lb) * 2, s); + wide_int rh_wub = wide_int::from (rh_ub, wi::get_precision (rh_ub) * 2, s); + + /* We don't expect a widening multiplication to be able to overflow but range + calculations for multiplications are complicated. After widening the + operands lets call the base class. */ + return op_mult.wi_fold (r, type, lh_wlb, lh_wub, rh_wlb, rh_wub); +} + + +class operator_widen_mult_unsigned : public range_operator +{ +public: + virtual void wi_fold (irange &r, tree type, + const wide_int &lh_lb, + const wide_int &lh_ub, + const wide_int &rh_lb, + const wide_int &rh_ub) + const; +} op_widen_mult_unsigned; +range_operator *ptr_op_widen_mult_unsigned = &op_widen_mult_unsigned; + +void +operator_widen_mult_unsigned::wi_fold (irange &r, tree type, + const wide_int &lh_lb, + const wide_int &lh_ub, + const wide_int &rh_lb, + const wide_int &rh_ub) const +{ + signop s = TYPE_SIGN (type); + + wide_int lh_wlb = wide_int::from (lh_lb, wi::get_precision (lh_lb) * 2, UNSIGNED); + wide_int lh_wub = wide_int::from (lh_ub, wi::get_precision (lh_ub) * 2, UNSIGNED); + wide_int rh_wlb = wide_int::from (rh_lb, wi::get_precision (rh_lb) * 2, s); + wide_int rh_wub = wide_int::from (rh_ub, wi::get_precision (rh_ub) * 2, s); + + /* We don't expect a widening multiplication to be able to overflow but range + calculations for multiplications are complicated. After widening the + operands lets call the base class. */ + return op_mult.wi_fold (r, type, lh_wlb, lh_wub, rh_wlb, rh_wub); +} class operator_div : public cross_product_operator { --N35aayhT7igGlY7K--