From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on2057.outbound.protection.outlook.com [40.107.21.57]) by sourceware.org (Postfix) with ESMTPS id 9DAD53858C27 for ; Wed, 27 Sep 2023 00:52:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9DAD53858C27 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=/jD/UCz5Z5ZtecMQ2eeGg7MNgWr464jEEi6DP0t48rw=; b=OhHeiKCVMmF4WvMMSqrG6mM90AKx7C5fPq3SXYxNHphANqyce+jxv3lFRQwG8a0OhjppVxD0IKbeOFTtIKNGOE0vN1+QWzDyuxW0/5tbgUn2OXBrb+DqCxUN0tPxrw65+0AB5s03zDndH7OCKf38/ARnO16j2w2qwUvicwJ9mrQ= Received: from AS9PR06CA0435.eurprd06.prod.outlook.com (2603:10a6:20b:49e::20) by AS2PR08MB10126.eurprd08.prod.outlook.com (2603:10a6:20b:645::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6813.28; Wed, 27 Sep 2023 00:52:41 +0000 Received: from AM7EUR03FT013.eop-EUR03.prod.protection.outlook.com (2603:10a6:20b:49e:cafe::c8) by AS9PR06CA0435.outlook.office365.com (2603:10a6:20b:49e::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6838.22 via Frontend Transport; Wed, 27 Sep 2023 00:52:41 +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 AM7EUR03FT013.mail.protection.outlook.com (100.127.140.191) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6838.21 via Frontend Transport; Wed, 27 Sep 2023 00:52:41 +0000 Received: ("Tessian outbound 169aaa6bf2b7:v175"); Wed, 27 Sep 2023 00:52:41 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: 90a6f89b4f5f07cc X-CR-MTA-TID: 64aa7808 Received: from 9c3f1ea8dd55.2 by 64aa7808-outbound-1.mta.getcheckrecipient.com id 3C514915-E6D3-458A-BE4A-996B1E4F334C.1; Wed, 27 Sep 2023 00:52:34 +0000 Received: from EUR04-HE1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id 9c3f1ea8dd55.2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Wed, 27 Sep 2023 00:52:34 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=SEKgWSGipYzdN8chmqARyaAnLHUWFE2u6iRAndbATXqYumtT2qFj6j8ZR9PncGjvRatmOqfrKtx/q7TtaEmdtSSgbiwYrOgMa9l2Mj6Z/stdcuI65HbbMFHSv2hCJ/hLmuhEUyAAx8XbgGy0ZpkAyCGTZxza6SHTXnfdBOVlZPWFx7FUVuqXf/tIQ0Ooz/XyAswyevzRdic/ZGy9uqX1zuhKV6I10nh3s57Vd9s7xurkMt6Ik3teVt2H16EAB5mi+O0GW+5rnPTFcyQrW18Cc8JlJT3iEnMpxQdEzqMDELb1rTDBtVTt154XYDZP8W6xWYrVrsrzm9+vacGyHHPrew== 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=/jD/UCz5Z5ZtecMQ2eeGg7MNgWr464jEEi6DP0t48rw=; b=Dz9ohCguI+JgjzIA5gw+D3NErLTg2EeoaCdEt3zuuDC2EGqeICy1YMEtwkzzHNfdSrMM1AJnpAWNdxvdw0uJJfnlC+CwghU3YcMG8g6qWTcCWxy+FX3uooIoW2Ls9ksgHGXLuYr76UZzfuENo7yHXNZ60RrU0nRhm5refuO6+Yz+Qf/+pAnMZUf35syAzv+8I+jY+94FLTZFnV4QhFgGEfVHipKclZIdSVM3Zdx+UjuRdGnVFjmY4P8vyv6q+ikxqSvo4wNbyzh4TVrawhkVpH8BKutarlgtAjc5LV7WlYD8i1v5NyAeFcDaxBl3gK69jMtZDOTa8tD+Qwjp3J0FDQ== 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=/jD/UCz5Z5ZtecMQ2eeGg7MNgWr464jEEi6DP0t48rw=; b=OhHeiKCVMmF4WvMMSqrG6mM90AKx7C5fPq3SXYxNHphANqyce+jxv3lFRQwG8a0OhjppVxD0IKbeOFTtIKNGOE0vN1+QWzDyuxW0/5tbgUn2OXBrb+DqCxUN0tPxrw65+0AB5s03zDndH7OCKf38/ARnO16j2w2qwUvicwJ9mrQ= 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 AS8PR08MB9743.eurprd08.prod.outlook.com (2603:10a6:20b:615::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6813.28; Wed, 27 Sep 2023 00:52:31 +0000 Received: from VI1PR08MB5325.eurprd08.prod.outlook.com ([fe80::662f:8e26:1bf8:aaa1]) by VI1PR08MB5325.eurprd08.prod.outlook.com ([fe80::662f:8e26:1bf8:aaa1%7]) with mapi id 15.20.6813.027; Wed, 27 Sep 2023 00:52:31 +0000 Date: Wed, 27 Sep 2023 01:52:29 +0100 From: Tamar Christina To: gcc-patches@gcc.gnu.org Cc: nd@arm.com, Richard.Earnshaw@arm.com, Marcus.Shawcroft@arm.com, Kyrylo.Tkachov@arm.com, richard.sandiford@arm.com Subject: [PATCH]AArch64 Add special patterns for creating DI scalar and vector constant 1 << 63 [PR109154] Message-ID: Content-Type: multipart/mixed; boundary="nPMmCxpXtlFgPZgF" Content-Disposition: inline X-ClientProxiedBy: LO4P123CA0560.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:33b::18) To VI1PR08MB5325.eurprd08.prod.outlook.com (2603:10a6:803:13e::17) MIME-Version: 1.0 X-MS-TrafficTypeDiagnostic: VI1PR08MB5325:EE_|AS8PR08MB9743:EE_|AM7EUR03FT013:EE_|AS2PR08MB10126:EE_ X-MS-Office365-Filtering-Correlation-Id: 85d780dd-5ea1-46b4-4d26-08dbbef40df4 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: ghWfNKZptayjkff4GmvA7D5evKLiqaKU71EHEv7NmZfK5OwOoV7DPYONAaY+EDj8JdOYozUCRY/pi8JbyFL9z/CzAmcZaJ2ohFTyQk8xArTF14JMhqyvjxyw9inQbZgOU17hRPyKS0AY3aUc69MSQXxlhk2x/Cr1e6cC3Ws2V9lPqNFMgyjSY+chspBN9ASgHPXX/aN7BgD9+KDPls8RUaQn8cvH2IVSq5Z420VSSQJ1xSEpKHq1P3vW7YCHS+ImvmeiwTnmDAx7p1IdrHe9qD3PcGKDJm6ByTKdLzYiLeU760dOsx5rblfYDso1zvD0HLrjab3GqKYNdY6UxluPJPwavzGHUrr472qDFH/eDNyU/nHVSAmVOkdFCOrNZBorA9zR8TDqpiCbeX3dIp9OWqS/mTYCU3UUhFy7XHNx4GzIhqadyD9mE5Wc9u2khK8OxHKgKdWHJoN8yhS6XHesxfnT/DcE9JZ2Hu5u+oYffdktE24rpeomzGdA3yPw/wpbO/pbaaqpVjWN/aIJvAjHlaVlRK+1z8kSXL4JIAYkePtXT2poDivLrSUW32Lw9WfCGF3maGeHBqH33oiuB+GGdNgt6BWdrDDwzOCBbWwuEYntGY1HcTGdKp63HD2wDVjA7wjaAwatGx2K2nxxR0miJDpYLlxqlu43tfvLYbjsOx0= 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:(13230031)(366004)(136003)(346002)(396003)(376002)(39860400002)(230922051799003)(1800799009)(186009)(451199024)(26005)(478600001)(86362001)(2616005)(36756003)(83380400001)(6486002)(6506007)(5660300002)(44144004)(38100700002)(33964004)(6512007)(8676002)(8936002)(2906002)(4326008)(316002)(41300700001)(84970400001)(66946007)(66476007)(66556008)(6916009)(235185007)(44832011)(4216001)(2700100001);DIR:OUT;SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS8PR08MB9743 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: AM7EUR03FT013.eop-EUR03.prod.protection.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: daad8328-6887-4d66-782e-08dbbef407d4 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: fWArVQD9bd3aORtjf4d6MLPh8venewOdW5xA9DnteqMsBbxlY+Xh5Tvgq+j+VIMvneIek/r4R3tfSVqe1noOHTlWenALPYFHF34QTfLtHP8zQl4mJeFmtpCsrSpSOdltN1pp1wAnO42sScC94p2AOgZSl7G6y3xqU8GafRug+QtcCEz6Lvm/M+eGQjc17rFpLs6UKtqqF75vGXjjJd5ng8uALaxs7s0ThcXA/DaEPgQ8t1oQX59HUlrh+Z1h6LUrHz1aUT4YMSVnXVtujtGxtPRJjYHGghrsXaq0OqatjEfuuTq9+RPvjtNzRdPpaGQEbkpVulIuQ3ctaZi6DUac8ohUrfVmf1ER2lb/qS9N7TJZvSeNDokY2SQk6pJcxYx2BVojOmvp5a8oOgWBTBTVsMtnp4kPfeBukQpU4koafYVo98X6uZ0qItd3dsbmBIhS4SWnYvFJ+7ylT2WawXbx5+aPLjvxUCUSVnx8lg3ErhIlZXq8PB26pY1uFalpSY2rtFFT9kweXQr08GxdSSySQjlW69Md3QliSg6tBx+Qyj7NqAHqMlpvE+ViCTZCp6Z2S66nrVaF66iv54lYrOUNxROOkyoaOQizBe3qAEGooY/l5msLztTpF3Lag+mBPjuYmq68uAWcelZ+KSBLzLpWDAYhSiZRVd1r4b5XpVJKFIfk/ZEY75gGXaXQ6fE4GYM8Wnprjlq2yH17aCO9jQOy/s9xr8ICwwjSLjufiNbSeAvbtLhyXIZVU3JVO1wNRgCg/UgheX5jMH2v1FcIAQVf+kg2Gj8aMer7FmJAchvhN5jmXHO8XCRwr/CdUHa5tbJG 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:(13230031)(4636009)(346002)(39860400002)(376002)(396003)(136003)(230922051799003)(1800799009)(82310400011)(186009)(451199024)(46966006)(40470700004)(36840700001)(6506007)(6486002)(40480700001)(82740400003)(356005)(40460700003)(2906002)(47076005)(83380400001)(235185007)(81166007)(36860700001)(44144004)(70206006)(33964004)(6512007)(70586007)(2616005)(26005)(5660300002)(8936002)(41300700001)(6916009)(8676002)(478600001)(4326008)(316002)(336012)(44832011)(36756003)(86362001)(84970400001)(4216001)(2700100001);DIR:OUT;SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Sep 2023 00:52:41.7531 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 85d780dd-5ea1-46b4-4d26-08dbbef40df4 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: AM7EUR03FT013.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS2PR08MB10126 X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,FORGED_SPF_HELO,GIT_PATCH_0,KAM_DMARC_NONE,KAM_LOTSOFHASH,KAM_SHORT,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,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: --nPMmCxpXtlFgPZgF Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Hi All, This adds a way to generate special sequences for creation of constants for which we don't have single instructions sequences which would have normally lead to a GP -> FP transfer or a literal load. The patch starts out by adding support for creating 1 << 63 using fneg (mov 0). Bootstrapped Regtested on aarch64-none-linux-gnu and no issues. Ok for master? Thanks, Tamar gcc/ChangeLog: PR tree-optimization/109154 * config/aarch64/aarch64-protos.h (aarch64_simd_special_constant_p): New. * config/aarch64/aarch64-simd.md (*aarch64_simd_mov): Add new coden for special constants. * config/aarch64/aarch64.cc (aarch64_extract_vec_duplicate_wide_int): Take optional mode. (aarch64_simd_special_constant_p): New. * config/aarch64/aarch64.md (*movdi_aarch64): Add new codegen for special constants. * config/aarch64/constraints.md (Dx): new. gcc/testsuite/ChangeLog: PR tree-optimization/109154 * gcc.target/aarch64/fneg-abs_1.c: Updated. * gcc.target/aarch64/fneg-abs_2.c: Updated. * gcc.target/aarch64/fneg-abs_4.c: Updated. --- inline copy of patch -- diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 70303d6fd953e0c397b9138ede8858c2db2e53db..2af9f6a774c20268bf90756c17064bbff8f8ff87 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -827,6 +827,7 @@ bool aarch64_sve_ptrue_svpattern_p (rtx, struct simd_immediate_info *); bool aarch64_simd_valid_immediate (rtx, struct simd_immediate_info *, enum simd_immediate_check w = AARCH64_CHECK_MOV); rtx aarch64_check_zero_based_sve_index_immediate (rtx); +bool aarch64_simd_special_constant_p (rtx, rtx, machine_mode); bool aarch64_sve_index_immediate_p (rtx); bool aarch64_sve_arith_immediate_p (machine_mode, rtx, bool); bool aarch64_sve_sqadd_sqsub_immediate_p (machine_mode, rtx, bool); diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 7b4d5a37a9795fefda785aaacc246918826ed0a2..63c802d942a186b5a94c66d2e83828a82a88ffa8 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -181,17 +181,28 @@ (define_insn_and_split "*aarch64_simd_mov" [?r , r ; multiple , * , 8] # [w , Dn; neon_move , simd, 4] << aarch64_output_simd_mov_immediate (operands[1], 128); [w , Dz; fmov , * , 4] fmov\t%d0, xzr + [w , Dx; neon_move , simd, 8] # } "&& reload_completed - && !(FP_REGNUM_P (REGNO (operands[0])) - && FP_REGNUM_P (REGNO (operands[1])))" + && (!(FP_REGNUM_P (REGNO (operands[0])) + && FP_REGNUM_P (REGNO (operands[1]))) + || (aarch64_simd_special_constant_p (operands[1], NULL_RTX, mode) + && FP_REGNUM_P (REGNO (operands[0]))))" [(const_int 0)] { if (GP_REGNUM_P (REGNO (operands[0])) && GP_REGNUM_P (REGNO (operands[1]))) aarch64_simd_emit_reg_reg_move (operands, DImode, 2); else - aarch64_split_simd_move (operands[0], operands[1]); + { + if (FP_REGNUM_P (REGNO (operands[0])) + && mode == V2DImode + && aarch64_simd_special_constant_p (operands[1], operands[0], + mode)) + ; + else + aarch64_split_simd_move (operands[0], operands[1]); + } DONE; } ) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 3739a44bfd909b69a76529cc6b0ae2f01d6fb36e..6e7ee446f1b31ee8bcf121c97c1c6fa87725bf42 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -11799,16 +11799,18 @@ aarch64_get_condition_code_1 (machine_mode mode, enum rtx_code comp_code) /* Return true if X is a CONST_INT, CONST_WIDE_INT or a constant vector duplicate of such constants. If so, store in RET_WI the wide_int representation of the constant paired with the inner mode of the vector mode - or TImode for scalar X constants. */ + or SMODE for scalar X constants. If SMODE is not provided then TImode is + used. */ static bool -aarch64_extract_vec_duplicate_wide_int (rtx x, wide_int *ret_wi) +aarch64_extract_vec_duplicate_wide_int (rtx x, wide_int *ret_wi, + scalar_mode mode = TImode) { rtx elt = unwrap_const_vec_duplicate (x); if (!CONST_SCALAR_INT_P (elt)) return false; scalar_mode smode - = CONST_SCALAR_INT_P (x) ? TImode : GET_MODE_INNER (GET_MODE (x)); + = CONST_SCALAR_INT_P (x) ? mode : GET_MODE_INNER (GET_MODE (x)); *ret_wi = rtx_mode_t (elt, smode); return true; } @@ -11857,6 +11859,43 @@ aarch64_const_vec_all_same_in_range_p (rtx x, && IN_RANGE (INTVAL (elt), minval, maxval)); } +/* Some constants can't be made using normal mov instructions in Advanced SIMD + but we can still create them in various ways. If the constant in VAL can be + created using alternate methods then if TARGET then return true and set + TARGET to the rtx for the sequence, otherwise return false if sequence is + not possible. */ + +bool +aarch64_simd_special_constant_p (rtx val, rtx target, machine_mode mode) +{ + wide_int wval; + machine_mode tmode = GET_MODE (val); + auto smode = GET_MODE_INNER (tmode != VOIDmode ? tmode : mode); + if (!aarch64_extract_vec_duplicate_wide_int (val, &wval, smode)) + return false; + + /* For Advanced SIMD we can create an integer with only the top bit set + using fneg (0.0f). */ + if (TARGET_SIMD + && !TARGET_SVE + && smode == DImode + && wi::only_sign_bit_p (wval)) + { + if (!target) + return true; + + /* Use the same base type as aarch64_gen_shareable_zero. */ + rtx zero = CONST0_RTX (V4SImode); + emit_move_insn (target, lowpart_subreg (mode, zero, V4SImode)); + rtx neg = lowpart_subreg (V2DFmode, target, mode); + emit_insn (gen_negv2df2 (neg, lowpart_subreg (V2DFmode, target, mode))); + emit_move_insn (target, lowpart_subreg (mode, neg, V2DFmode)); + return true; + } + + return false; +} + bool aarch64_const_vec_all_same_int_p (rtx x, HOST_WIDE_INT val) { diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 634cfd33b41d0f945ca00d8efc9eff1ede490544..b51f979dba12b726bff0c1109b75c6d2c7ae41ab 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -1340,13 +1340,21 @@ (define_insn_and_split "*movdi_aarch64" [r, w ; f_mrc , fp , 4] fmov\t%x0, %d1 [w, w ; fmov , fp , 4] fmov\t%d0, %d1 [w, Dd ; neon_move, simd, 4] << aarch64_output_scalar_simd_mov_immediate (operands[1], DImode); + [w, Dx ; neon_move, simd, 8] # } - "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), DImode) - && REG_P (operands[0]) && GP_REGNUM_P (REGNO (operands[0]))" + "CONST_INT_P (operands[1]) + && REG_P (operands[0]) + && ((!aarch64_move_imm (INTVAL (operands[1]), DImode) + && GP_REGNUM_P (REGNO (operands[0]))) + || (aarch64_simd_special_constant_p (operands[1], NULL_RTX, DImode) + && FP_REGNUM_P (REGNO (operands[0]))))" [(const_int 0)] { + if (GP_REGNUM_P (REGNO (operands[0]))) aarch64_expand_mov_immediate (operands[0], operands[1]); - DONE; + else + aarch64_simd_special_constant_p (operands[1], operands[0], DImode); + DONE; } ) diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md index 371a00827d84d8ea4a06ba2b00a761d3b179ae90..11cf5a0d16b3364a7a4d0b2a2e5bb33063151479 100644 --- a/gcc/config/aarch64/constraints.md +++ b/gcc/config/aarch64/constraints.md @@ -488,6 +488,14 @@ (define_constraint "Dr" (and (match_code "const,const_vector") (match_test "aarch64_simd_shift_imm_p (op, GET_MODE (op), false)"))) + +(define_constraint "Dx" + "@internal + A constraint that matches a vector of 64-bit immediates which we don't have a + single instruction to create but that we can create in creative ways." + (and (match_code "const_int,const,const_vector") + (match_test "aarch64_simd_special_constant_p (op, NULL_RTX, DImode)"))) + (define_constraint "Dz" "@internal A constraint that matches a vector of immediate zero." diff --git a/gcc/testsuite/gcc.target/aarch64/fneg-abs_1.c b/gcc/testsuite/gcc.target/aarch64/fneg-abs_1.c index f823013c3ddf6b3a266c3abfcbf2642fc2a75fa6..43c37e21b50e13c09b8d6850686e88465cd8482a 100644 --- a/gcc/testsuite/gcc.target/aarch64/fneg-abs_1.c +++ b/gcc/testsuite/gcc.target/aarch64/fneg-abs_1.c @@ -28,8 +28,8 @@ float32x4_t t2 (float32x4_t a) /* ** t3: -** adrp x0, .LC[0-9]+ -** ldr q[0-9]+, \[x0, #:lo12:.LC0\] +** movi v[0-9]+.4s, 0 +** fneg v[0-9]+.2d, v[0-9]+.2d ** orr v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ** ret */ diff --git a/gcc/testsuite/gcc.target/aarch64/fneg-abs_2.c b/gcc/testsuite/gcc.target/aarch64/fneg-abs_2.c index 141121176b309e4b2aa413dc55271a6e3c93d5e1..fb14ec3e2210e0feeff80f2410d777d3046a9f78 100644 --- a/gcc/testsuite/gcc.target/aarch64/fneg-abs_2.c +++ b/gcc/testsuite/gcc.target/aarch64/fneg-abs_2.c @@ -20,8 +20,8 @@ float32_t f1 (float32_t a) /* ** f2: -** mov x0, -9223372036854775808 -** fmov d[0-9]+, x0 +** fmov d[0-9]+, xzr +** fneg v[0-9]+.2d, v[0-9]+.2d ** orr v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ** ret */ @@ -29,3 +29,4 @@ float64_t f2 (float64_t a) { return -fabs (a); } + diff --git a/gcc/testsuite/gcc.target/aarch64/fneg-abs_4.c b/gcc/testsuite/gcc.target/aarch64/fneg-abs_4.c index 10879dea74462d34b26160eeb0bd54ead063166b..4ea0105f6c0a9756070bcc60d34f142f53d8242c 100644 --- a/gcc/testsuite/gcc.target/aarch64/fneg-abs_4.c +++ b/gcc/testsuite/gcc.target/aarch64/fneg-abs_4.c @@ -8,8 +8,8 @@ /* ** negabs: -** mov x0, -9223372036854775808 -** fmov d[0-9]+, x0 +** fmov d[0-9]+, xzr +** fneg v[0-9]+.2d, v[0-9]+.2d ** orr v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ** ret */ -- --nPMmCxpXtlFgPZgF Content-Type: text/plain; charset=utf-8 Content-Disposition: attachment; filename="rb17722.patch" diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 70303d6fd953e0c397b9138ede8858c2db2e53db..2af9f6a774c20268bf90756c17064bbff8f8ff87 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -827,6 +827,7 @@ bool aarch64_sve_ptrue_svpattern_p (rtx, struct simd_immediate_info *); bool aarch64_simd_valid_immediate (rtx, struct simd_immediate_info *, enum simd_immediate_check w = AARCH64_CHECK_MOV); rtx aarch64_check_zero_based_sve_index_immediate (rtx); +bool aarch64_simd_special_constant_p (rtx, rtx, machine_mode); bool aarch64_sve_index_immediate_p (rtx); bool aarch64_sve_arith_immediate_p (machine_mode, rtx, bool); bool aarch64_sve_sqadd_sqsub_immediate_p (machine_mode, rtx, bool); diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 7b4d5a37a9795fefda785aaacc246918826ed0a2..63c802d942a186b5a94c66d2e83828a82a88ffa8 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -181,17 +181,28 @@ (define_insn_and_split "*aarch64_simd_mov" [?r , r ; multiple , * , 8] # [w , Dn; neon_move , simd, 4] << aarch64_output_simd_mov_immediate (operands[1], 128); [w , Dz; fmov , * , 4] fmov\t%d0, xzr + [w , Dx; neon_move , simd, 8] # } "&& reload_completed - && !(FP_REGNUM_P (REGNO (operands[0])) - && FP_REGNUM_P (REGNO (operands[1])))" + && (!(FP_REGNUM_P (REGNO (operands[0])) + && FP_REGNUM_P (REGNO (operands[1]))) + || (aarch64_simd_special_constant_p (operands[1], NULL_RTX, mode) + && FP_REGNUM_P (REGNO (operands[0]))))" [(const_int 0)] { if (GP_REGNUM_P (REGNO (operands[0])) && GP_REGNUM_P (REGNO (operands[1]))) aarch64_simd_emit_reg_reg_move (operands, DImode, 2); else - aarch64_split_simd_move (operands[0], operands[1]); + { + if (FP_REGNUM_P (REGNO (operands[0])) + && mode == V2DImode + && aarch64_simd_special_constant_p (operands[1], operands[0], + mode)) + ; + else + aarch64_split_simd_move (operands[0], operands[1]); + } DONE; } ) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 3739a44bfd909b69a76529cc6b0ae2f01d6fb36e..6e7ee446f1b31ee8bcf121c97c1c6fa87725bf42 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -11799,16 +11799,18 @@ aarch64_get_condition_code_1 (machine_mode mode, enum rtx_code comp_code) /* Return true if X is a CONST_INT, CONST_WIDE_INT or a constant vector duplicate of such constants. If so, store in RET_WI the wide_int representation of the constant paired with the inner mode of the vector mode - or TImode for scalar X constants. */ + or SMODE for scalar X constants. If SMODE is not provided then TImode is + used. */ static bool -aarch64_extract_vec_duplicate_wide_int (rtx x, wide_int *ret_wi) +aarch64_extract_vec_duplicate_wide_int (rtx x, wide_int *ret_wi, + scalar_mode mode = TImode) { rtx elt = unwrap_const_vec_duplicate (x); if (!CONST_SCALAR_INT_P (elt)) return false; scalar_mode smode - = CONST_SCALAR_INT_P (x) ? TImode : GET_MODE_INNER (GET_MODE (x)); + = CONST_SCALAR_INT_P (x) ? mode : GET_MODE_INNER (GET_MODE (x)); *ret_wi = rtx_mode_t (elt, smode); return true; } @@ -11857,6 +11859,43 @@ aarch64_const_vec_all_same_in_range_p (rtx x, && IN_RANGE (INTVAL (elt), minval, maxval)); } +/* Some constants can't be made using normal mov instructions in Advanced SIMD + but we can still create them in various ways. If the constant in VAL can be + created using alternate methods then if TARGET then return true and set + TARGET to the rtx for the sequence, otherwise return false if sequence is + not possible. */ + +bool +aarch64_simd_special_constant_p (rtx val, rtx target, machine_mode mode) +{ + wide_int wval; + machine_mode tmode = GET_MODE (val); + auto smode = GET_MODE_INNER (tmode != VOIDmode ? tmode : mode); + if (!aarch64_extract_vec_duplicate_wide_int (val, &wval, smode)) + return false; + + /* For Advanced SIMD we can create an integer with only the top bit set + using fneg (0.0f). */ + if (TARGET_SIMD + && !TARGET_SVE + && smode == DImode + && wi::only_sign_bit_p (wval)) + { + if (!target) + return true; + + /* Use the same base type as aarch64_gen_shareable_zero. */ + rtx zero = CONST0_RTX (V4SImode); + emit_move_insn (target, lowpart_subreg (mode, zero, V4SImode)); + rtx neg = lowpart_subreg (V2DFmode, target, mode); + emit_insn (gen_negv2df2 (neg, lowpart_subreg (V2DFmode, target, mode))); + emit_move_insn (target, lowpart_subreg (mode, neg, V2DFmode)); + return true; + } + + return false; +} + bool aarch64_const_vec_all_same_int_p (rtx x, HOST_WIDE_INT val) { diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 634cfd33b41d0f945ca00d8efc9eff1ede490544..b51f979dba12b726bff0c1109b75c6d2c7ae41ab 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -1340,13 +1340,21 @@ (define_insn_and_split "*movdi_aarch64" [r, w ; f_mrc , fp , 4] fmov\t%x0, %d1 [w, w ; fmov , fp , 4] fmov\t%d0, %d1 [w, Dd ; neon_move, simd, 4] << aarch64_output_scalar_simd_mov_immediate (operands[1], DImode); + [w, Dx ; neon_move, simd, 8] # } - "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), DImode) - && REG_P (operands[0]) && GP_REGNUM_P (REGNO (operands[0]))" + "CONST_INT_P (operands[1]) + && REG_P (operands[0]) + && ((!aarch64_move_imm (INTVAL (operands[1]), DImode) + && GP_REGNUM_P (REGNO (operands[0]))) + || (aarch64_simd_special_constant_p (operands[1], NULL_RTX, DImode) + && FP_REGNUM_P (REGNO (operands[0]))))" [(const_int 0)] { + if (GP_REGNUM_P (REGNO (operands[0]))) aarch64_expand_mov_immediate (operands[0], operands[1]); - DONE; + else + aarch64_simd_special_constant_p (operands[1], operands[0], DImode); + DONE; } ) diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md index 371a00827d84d8ea4a06ba2b00a761d3b179ae90..11cf5a0d16b3364a7a4d0b2a2e5bb33063151479 100644 --- a/gcc/config/aarch64/constraints.md +++ b/gcc/config/aarch64/constraints.md @@ -488,6 +488,14 @@ (define_constraint "Dr" (and (match_code "const,const_vector") (match_test "aarch64_simd_shift_imm_p (op, GET_MODE (op), false)"))) + +(define_constraint "Dx" + "@internal + A constraint that matches a vector of 64-bit immediates which we don't have a + single instruction to create but that we can create in creative ways." + (and (match_code "const_int,const,const_vector") + (match_test "aarch64_simd_special_constant_p (op, NULL_RTX, DImode)"))) + (define_constraint "Dz" "@internal A constraint that matches a vector of immediate zero." diff --git a/gcc/testsuite/gcc.target/aarch64/fneg-abs_1.c b/gcc/testsuite/gcc.target/aarch64/fneg-abs_1.c index f823013c3ddf6b3a266c3abfcbf2642fc2a75fa6..43c37e21b50e13c09b8d6850686e88465cd8482a 100644 --- a/gcc/testsuite/gcc.target/aarch64/fneg-abs_1.c +++ b/gcc/testsuite/gcc.target/aarch64/fneg-abs_1.c @@ -28,8 +28,8 @@ float32x4_t t2 (float32x4_t a) /* ** t3: -** adrp x0, .LC[0-9]+ -** ldr q[0-9]+, \[x0, #:lo12:.LC0\] +** movi v[0-9]+.4s, 0 +** fneg v[0-9]+.2d, v[0-9]+.2d ** orr v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ** ret */ diff --git a/gcc/testsuite/gcc.target/aarch64/fneg-abs_2.c b/gcc/testsuite/gcc.target/aarch64/fneg-abs_2.c index 141121176b309e4b2aa413dc55271a6e3c93d5e1..fb14ec3e2210e0feeff80f2410d777d3046a9f78 100644 --- a/gcc/testsuite/gcc.target/aarch64/fneg-abs_2.c +++ b/gcc/testsuite/gcc.target/aarch64/fneg-abs_2.c @@ -20,8 +20,8 @@ float32_t f1 (float32_t a) /* ** f2: -** mov x0, -9223372036854775808 -** fmov d[0-9]+, x0 +** fmov d[0-9]+, xzr +** fneg v[0-9]+.2d, v[0-9]+.2d ** orr v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ** ret */ @@ -29,3 +29,4 @@ float64_t f2 (float64_t a) { return -fabs (a); } + diff --git a/gcc/testsuite/gcc.target/aarch64/fneg-abs_4.c b/gcc/testsuite/gcc.target/aarch64/fneg-abs_4.c index 10879dea74462d34b26160eeb0bd54ead063166b..4ea0105f6c0a9756070bcc60d34f142f53d8242c 100644 --- a/gcc/testsuite/gcc.target/aarch64/fneg-abs_4.c +++ b/gcc/testsuite/gcc.target/aarch64/fneg-abs_4.c @@ -8,8 +8,8 @@ /* ** negabs: -** mov x0, -9223372036854775808 -** fmov d[0-9]+, x0 +** fmov d[0-9]+, xzr +** fneg v[0-9]+.2d, v[0-9]+.2d ** orr v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ** ret */ --nPMmCxpXtlFgPZgF--