From patchwork Mon May 4 12:53:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 1282610 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49G2pW59n5z9sSc for ; Mon, 4 May 2020 22:53:22 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 242FB383E807; Mon, 4 May 2020 12:53:19 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 3B1E7383E804 for ; Mon, 4 May 2020 12:53:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 3B1E7383E804 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=richard.sandiford@arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id EE03C1FB for ; Mon, 4 May 2020 05:53:13 -0700 (PDT) Received: from localhost (e121540-lin.manchester.arm.com [10.32.98.126]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9523B3F71F for ; Mon, 4 May 2020 05:53:13 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [PATCH] internal-fn: Avoid dropping the lhs of some calls [PR94941] Date: Mon, 04 May 2020 13:53:12 +0100 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) MIME-Version: 1.0 X-Spam-Status: No, score=-25.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" create_output_operand coerces an output operand to the insn's predicates, using a suggested rtx location if convenient. But if that rtx location is actually required rather than optional, the builder of the insn has to emit a move afterwards. (We could instead add a new interface that does this automatically, but that's future work.) This PR shows that we were failing to emit the move for some of the vector load internal functions. I think there are other routines in internal-fn.c that potentially have the same problem, but this patch is supposed to be a conservative subset suitable for backporting to GCC 10. Tested on aarch64-linux-gnu (with and without SVE), arm-linux-gnueabihf and x86_64-linux-gnu. OK for trunk and GCC 10 branch? It would be nice if we could have this for GCC 10.1, but I realise it wouldn't justify a new RC on its own, so I'll assume that "GCC 10 branch" is "GCC 10 branch after the release". Richard 2020-05-04 Richard Sandiford gcc/ PR middle-end/94941 * internal-fn.c (expand_load_lanes_optab_fn): Emit a move if the chosen lhs is different from the gcall lhs. (expand_mask_load_optab_fn): Likewise. (expand_gather_load_optab_fn): Likewise. gcc/testsuite/ PR middle-end/94941 * gcc.target/aarch64/sve/acle/general/unoptimized_1.c: New test. --- gcc/internal-fn.c | 6 ++++++ .../aarch64/sve/acle/general/unoptimized_1.c | 21 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/acle/general/unoptimized_1.c diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c index 52d1638917a..5e9aa60721e 100644 --- a/gcc/internal-fn.c +++ b/gcc/internal-fn.c @@ -167,6 +167,8 @@ expand_load_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab) create_output_operand (&ops[0], target, TYPE_MODE (type)); create_fixed_operand (&ops[1], mem); expand_insn (get_multi_vector_move (type, optab), 2, ops); + if (!rtx_equal_p (target, ops[0].value)) + emit_move_insn (target, ops[0].value); } /* Expand STORE_LANES call STMT using optab OPTAB. */ @@ -2507,6 +2509,8 @@ expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab) create_fixed_operand (&ops[1], mem); create_input_operand (&ops[2], mask, TYPE_MODE (TREE_TYPE (maskt))); expand_insn (icode, 3, ops); + if (!rtx_equal_p (target, ops[0].value)) + emit_move_insn (target, ops[0].value); } #define expand_mask_load_lanes_optab_fn expand_mask_load_optab_fn @@ -2827,6 +2831,8 @@ expand_gather_load_optab_fn (internal_fn, gcall *stmt, direct_optab optab) insn_code icode = convert_optab_handler (optab, TYPE_MODE (TREE_TYPE (lhs)), TYPE_MODE (TREE_TYPE (offset))); expand_insn (icode, i, ops); + if (!rtx_equal_p (lhs_rtx, ops[0].value)) + emit_move_insn (lhs_rtx, ops[0].value); } /* Expand DIVMOD() using: diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/unoptimized_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/unoptimized_1.c new file mode 100644 index 00000000000..18d73e21a83 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/unoptimized_1.c @@ -0,0 +1,21 @@ +/* { dg-do run { target aarch64_sve_hw } } */ + +#include + +svfloat32_t +foo (float *ptr) +{ + svbool_t pg = svptrue_pat_b32 (SV_VL1); + svfloat32_t res = svld1 (pg, ptr); + return res; +} + +int +main (void) +{ + svbool_t pg = svptrue_pat_b32 (SV_VL1); + float x[1] = { 1 }; + if (svptest_any (pg, svcmpne (pg, foo (x), 1.0))) + __builtin_abort (); + return 0; +}