From patchwork Fri Sep 27 13:17:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Andre Vieira (lists)" X-Patchwork-Id: 1990283 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XFWHt1QmLz1xt9 for ; Fri, 27 Sep 2024 23:18:34 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3D838385C6C6 for ; Fri, 27 Sep 2024 13:18:32 +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 74E533858408 for ; Fri, 27 Sep 2024 13:18:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 74E533858408 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 74E533858408 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1727443093; cv=none; b=DL8TpQpoW3CMA0eFBa8Hz2NuFhbXKNGFp0q2ia+h5w+VHrqkFNwORg7JupsyRDRS/gYwxfb/xI4ij3YP/udBgygIQuWda+/JyNvMBJPi0oJbV5pxo/imbAlcSNe+GQ8M5jxmampoHnRNBLdKqipLRr2uRdehB2ATFbRVFNIz02Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1727443093; c=relaxed/simple; bh=yeENa4meYkRCZqH8IWLj9AD3Ep0pdC47hM9Z+hdcpVg=; h=Message-ID:Date:MIME-Version:To:From:Subject; b=QQnoHrSAXj1Wrzl0dejXDW1urjjbeeX0IKh+YYjFWp4ll1K45Q1lA0lM7lfbYxEpM6itgbfu8Xm46tNa0w95MW5xr6P6+jVcsxGfaTNJxBKp143vDoIBAKAQvaRWbPKpjtuaUz9dLeAwidpQYdOfxrqThBlXdU9TjmE7PECYbgU= ARC-Authentication-Results: i=1; server2.sourceware.org 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 897D214BF; Fri, 27 Sep 2024 06:18:29 -0700 (PDT) Received: from [10.57.21.8] (unknown [10.57.21.8]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 768AF3F587; Fri, 27 Sep 2024 06:17:59 -0700 (PDT) Message-ID: <7755bd1c-b454-4b19-84b5-92db022ff175@arm.com> Date: Fri, 27 Sep 2024 14:17:58 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-US To: "gcc-patches@gcc.gnu.org" Cc: "richard.earnshaw@arm.com" , Christophe.Lyon@arm.com From: "Andre Vieira (lists)" Subject: [PATCH v2] arm: Prevent ICE when doloop dec_set is not PLUS_EXPR X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, KAM_SHORT, SPF_HELO_NONE, SPF_NONE, TXREP 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.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org Resending as v2 so CI picks it up. This patch refactors and fixes an issue where arm_mve_dlstp_check_dec_counter was making an assumption about the form of what a candidate for a dec_insn. This dec_insn is the instruction that decreases the loop counter inside a decrementing loop and we expect it to have the following form: (set (reg CONDCOUNT) (plus (reg CONDCOUNT) (const_int))) Where CONDCOUNT is the loop counter, and const int is the negative constant used to decrement it. This patch also improves our search for a valid dec_insn. Before this patch we'd only look for a dec_insn inside the loop header if the loop latch was empty. We now also search the loop header if the loop latch is not empty but the last instruction is not a valid dec_insn. This could potentially be improved to search all instructions inside the loop latch. gcc/ChangeLog: * config/arm/arm.cc (check_dec_insn): New helper function containing code hoisted from... (arm_mve_dlstp_check_dec_counter): ... here. Use check_dec_insn to check the validity of the candidate dec_insn. gcc/testsuite/ChangeLog: * gcc.targer/arm/mve/dlstp-loop-form.c: New test. diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc index 92cd168e65937ef7350477464e8b0becf85bceed..363a972170b37275372bb8bf30d510876021c8c0 100644 --- a/gcc/config/arm/arm.cc +++ b/gcc/config/arm/arm.cc @@ -35214,6 +35214,32 @@ arm_mve_dlstp_check_inc_counter (loop *loop, rtx_insn* vctp_insn, return vctp_insn; } +/* Helper function to 'arm_mve_dlstp_check_dec_counter' to make sure DEC_INSN + is of the expected form: + (set (reg a) (plus (reg a) (const_int))) + where (reg a) is the same as CONDCOUNT. + Return a rtx with the set if it is in the right format or NULL_RTX + otherwise. */ + +static rtx +check_dec_insn (rtx_insn *dec_insn, rtx condcount) +{ + if (!NONDEBUG_INSN_P (dec_insn)) + return NULL_RTX; + rtx dec_set = single_set (dec_insn); + if (!dec_set + || !REG_P (SET_DEST (dec_set)) + || GET_CODE (SET_SRC (dec_set)) != PLUS + || !REG_P (XEXP (SET_SRC (dec_set), 0)) + || !CONST_INT_P (XEXP (SET_SRC (dec_set), 1)) + || REGNO (SET_DEST (dec_set)) + != REGNO (XEXP (SET_SRC (dec_set), 0)) + || REGNO (SET_DEST (dec_set)) != REGNO (condcount)) + return NULL_RTX; + + return dec_set; +} + /* Helper function to `arm_mve_loop_valid_for_dlstp`. In the case of a counter that is decrementing, ensure that it is decrementing by the right amount in each iteration and that the target condition is what @@ -35230,30 +35256,19 @@ arm_mve_dlstp_check_dec_counter (loop *loop, rtx_insn* vctp_insn, loop latch. Here we simply need to verify that this counter is the same reg that is also used in the vctp_insn and that it is not otherwise modified. */ - rtx_insn *dec_insn = BB_END (loop->latch); + rtx dec_set = check_dec_insn (BB_END (loop->latch), condcount); /* If not in the loop latch, try to find the decrement in the loop header. */ - if (!NONDEBUG_INSN_P (dec_insn)) + if (dec_set == NULL_RTX) { df_ref temp = df_bb_regno_only_def_find (loop->header, REGNO (condcount)); /* If we haven't been able to find the decrement, bail out. */ if (!temp) return NULL; - dec_insn = DF_REF_INSN (temp); - } - - rtx dec_set = single_set (dec_insn); + dec_set = check_dec_insn (DF_REF_INSN (temp), condcount); - /* Next, ensure that it is a PLUS of the form: - (set (reg a) (plus (reg a) (const_int))) - where (reg a) is the same as condcount. */ - if (!dec_set - || !REG_P (SET_DEST (dec_set)) - || !REG_P (XEXP (SET_SRC (dec_set), 0)) - || !CONST_INT_P (XEXP (SET_SRC (dec_set), 1)) - || REGNO (SET_DEST (dec_set)) - != REGNO (XEXP (SET_SRC (dec_set), 0)) - || REGNO (SET_DEST (dec_set)) != REGNO (condcount)) - return NULL; + if (dec_set == NULL_RTX) + return NULL; + } decrementnum = INTVAL (XEXP (SET_SRC (dec_set), 1)); diff --git a/gcc/testsuite/gcc.target/arm/mve/dlstp-loop-form.c b/gcc/testsuite/gcc.target/arm/mve/dlstp-loop-form.c new file mode 100644 index 0000000000000000000000000000000000000000..a1b26873d7908035c726e3724c91b186c697bc60 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/dlstp-loop-form.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */ +/* { dg-options "-Ofast" } */ +/* { dg-add-options arm_v8_1m_mve_fp } */ +#pragma GCC arm "arm_mve_types.h" +#pragma GCC arm "arm_mve.h" false +typedef __attribute__((aligned(2))) float16x8_t e; +mve_pred16_t c(long d) { return __builtin_mve_vctp16qv8bi(d); } +int f(); +void n() { + int g, h, *i, j; + mve_pred16_t k; + e acc; + e l; + e m; + for (;;) { + j = g; + acc[g]; + for (; h < g; h += 8) { + k = c(j); + acc = vfmsq_m(acc, l, m, k); + j -= 8; + } + i[g] = f(acc); + } +} +