From patchwork Thu Dec 28 15:35:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roger Sayle X-Patchwork-Id: 1880874 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=nextmovesoftware.com header.i=@nextmovesoftware.com header.a=rsa-sha256 header.s=default header.b=JgBNusyV; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; 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 [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 ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4T1CJs2WCnz1ydb for ; Fri, 29 Dec 2023 02:35:54 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6750938582BF for ; Thu, 28 Dec 2023 15:35:52 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from server.nextmovesoftware.com (server.nextmovesoftware.com [162.254.253.69]) by sourceware.org (Postfix) with ESMTPS id D1F3C3858292 for ; Thu, 28 Dec 2023 15:35:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D1F3C3858292 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=nextmovesoftware.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nextmovesoftware.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org D1F3C3858292 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=162.254.253.69 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1703777730; cv=none; b=tv5L/W1HKEKbxzAH7YKHRAFdCvJ5BL/P+xTSYMBw73kkn2bkSISJC1WB95ueIERWcHsjdpcOCprT985NyAHEgVvIQ+yzOEM9n2G9RIAtwej+i8lPvdjobpuojrq+kR0hZZvd/HH+FfEEwPshLDAgSWN7LCe4yd+ktm3kX4BE5lc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1703777730; c=relaxed/simple; bh=u6mkodk16iaueyv5BOwX3j0ctNgGpNs4LP1RK3UNbI0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=V4FlAXSRxT6+BcydaPBClXemcCbuVzjEjGE8ToYb9wjUJ6W8OB1bxcQuI/S27oZDPU5k2EbKlbov7TTBavytS8huZ8+pVnuB/azY/mlKGyQKwpFTyHZZCDYAYcNLTBOwmRPg9g6QJTY46nJylbuo11AeKe4w3UD2UeYzkQ+SIkQ= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nextmovesoftware.com; s=default; h=Content-Type:MIME-Version:Message-ID: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=9ZAyh11tbgYkZ+5AIrNWZAKhg3dIXcPNRqMj6nZ50Bk=; b=JgBNusyV3L6FISZga4N0pbkUY6 iI2Cs6ygUbRG4lPMSnmYZRmxzfLAVu7Z7CJdo3UY9E4bRyZl9obfZ0z+ox20/nIYUNeRFBpT+STcI yFkIdyu+JtRJvz4l98rTmfYZhTpKjZStD9P8O6uT8hQs0DLSwSAQlfQvoqAhjPtRRZlIZN6/7D0w4 bmiYCtErgw5w6q8vQkSskjVWr9jYeOOJf01biKbcw0MHbBHmaa6QhZUDJuiTXCM09/53cqAN8pjhF chQ0uqViq7atK7EcHetMzmXi8u75usF5MRIeqPBPPk3KQwpf50cmyc11GAT3p+xd5Mko/zjgOxUzs g54YjeYQ==; Received: from [185.62.158.67] (port=59333 helo=Dell) by server.nextmovesoftware.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96.2) (envelope-from ) id 1rIsPv-0007bt-0z; Thu, 28 Dec 2023 10:35:27 -0500 From: "Roger Sayle" To: Cc: "'Jeff Law'" Subject: [middle-end PATCH] Only call targetm.truly_noop_truncation for truncations. Date: Thu, 28 Dec 2023 15:35:25 -0000 Message-ID: <009701da39a3$7b406080$71c12180$@nextmovesoftware.com> MIME-Version: 1.0 X-Mailer: Microsoft Outlook 16.0 Thread-Index: Ado5otoWk3pYen/vQUy+1QZhytLQ/w== Content-Language: en-gb X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - server.nextmovesoftware.com X-AntiAbuse: Original Domain - gcc.gnu.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - nextmovesoftware.com X-Get-Message-Sender-Via: server.nextmovesoftware.com: authenticated_id: roger@nextmovesoftware.com X-Authenticated-Sender: server.nextmovesoftware.com: roger@nextmovesoftware.com X-Source: X-Source-Args: X-Source-Dir: X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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 The truly_noop_truncation target hook is documented, in target.def, as "true if it is safe to convert a value of inprec bits to one of outprec bits (where outprec is smaller than inprec) by merely operating on it as if it had only outprec bits", i.e. the middle-end can use a SUBREG instead of a TRUNCATE. What's perhaps potentially a little ambiguous in the above description is whether it is the caller or the callee that's responsible for ensuring or checking whether "outprec < inprec". The name TRULY_NOOP_TRUNCATION_P, like SUBREG_PROMOTED_P, may be prone to being understood as a predicate that confirms that something is a no-op truncation or a promoted subreg, when in fact the caller must first confirm this is a truncation/subreg and only then call the "classification" macro. Alas making the following minor tweak (for testing) to the i386 backend: static bool ix86_truly_noop_truncation (poly_uint64 outprec, poly_uint64 inprec) { gcc_assert (outprec < inprec); return true; } #undef TARGET_TRULY_NOOP_TRUNCATION #define TARGET_TRULY_NOOP_TRUNCATION ix86_truly_noop_truncation reveals that there are numerous callers in middle-end that rely on the default behaviour of silently returning true for any (invalid) input. These are fixed below. This patch has been tested on x86_64-pc-linux-gnu with make bootstrap and make -k check, both with and without --target_board=unix{-m32} with no new failures. Ok for mainline? 2023-12-28 Roger Sayle gcc/ChangeLog * combine.cc (make_extraction): Confirm that OUTPREC is less than INPREC before calling TRULY_NOOP_TRUNCATION_MODES_P. * expmed.cc (store_bit_field_using_insv): Likewise. (extract_bit_field_using_extv): Likewise. (extract_bit_field_as_subreg): Likewise. * optabs-query.cc (get_best_extraction_insn): Likewise. * optabs.cc (expand_parity): Likewise. * rtlhooks.cc (gen_lowpart_general): Likewise. * simplify-rtx.cc (simplify_truncation): Disallow truncations to the same precision. (simplify_unary_operation_1) : Move optimization of truncations to the same mode earlier. Thanks in advance, Roger diff --git a/gcc/combine.cc b/gcc/combine.cc index f2c64a9..5aa2f57 100644 --- a/gcc/combine.cc +++ b/gcc/combine.cc @@ -7613,7 +7613,8 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos, && (pos == 0 || REG_P (inner)) && (inner_mode == tmode || !REG_P (inner) - || TRULY_NOOP_TRUNCATION_MODES_P (tmode, inner_mode) + || (known_lt (GET_MODE_SIZE (tmode), GET_MODE_SIZE (inner_mode)) + && TRULY_NOOP_TRUNCATION_MODES_P (tmode, inner_mode)) || reg_truncated_to_mode (tmode, inner)) && (! in_dest || (REG_P (inner) @@ -7856,6 +7857,8 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos, /* On the LHS, don't create paradoxical subregs implicitely truncating the register unless TARGET_TRULY_NOOP_TRUNCATION. */ if (in_dest + && known_lt (GET_MODE_SIZE (GET_MODE (inner)), + GET_MODE_SIZE (wanted_inner_mode)) && !TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (inner), wanted_inner_mode)) return NULL_RTX; diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 0bba93f..8940d47 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -26707,6 +26707,16 @@ ix86_libm_function_max_error (unsigned cfn, machine_mode mode, #define TARGET_RUN_TARGET_SELFTESTS selftest::ix86_run_selftests #endif /* #if CHECKING_P */ +static bool +ix86_truly_noop_truncation (poly_uint64 outprec, poly_uint64 inprec) +{ + gcc_assert (outprec < inprec); + return true; +} + +#undef TARGET_TRULY_NOOP_TRUNCATION +#define TARGET_TRULY_NOOP_TRUNCATION ix86_truly_noop_truncation + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-i386.h" diff --git a/gcc/expmed.cc b/gcc/expmed.cc index 05331dd..6398bf9 100644 --- a/gcc/expmed.cc +++ b/gcc/expmed.cc @@ -651,6 +651,7 @@ store_bit_field_using_insv (const extraction_insn *insv, rtx op0, X) 0)) is (reg:N X). */ if (GET_CODE (xop0) == SUBREG && REG_P (SUBREG_REG (xop0)) + && paradoxical_subreg_p (xop0) && !TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (SUBREG_REG (xop0)), op_mode)) { @@ -1585,7 +1586,11 @@ extract_bit_field_using_extv (const extraction_insn *extv, rtx op0, mode. Instead, create a temporary and use convert_move to set the target. */ if (REG_P (target) - && TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (target), ext_mode) + && (known_lt (GET_MODE_SIZE (GET_MODE (target)), + GET_MODE_SIZE (ext_mode)) + ? TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (target), ext_mode) + : known_eq (GET_MODE_SIZE (GET_MODE (target)), + GET_MODE_SIZE (ext_mode))) && (temp = gen_lowpart_if_possible (ext_mode, target))) { target = temp; @@ -1626,7 +1631,9 @@ extract_bit_field_as_subreg (machine_mode mode, rtx op0, if (multiple_p (bitnum, BITS_PER_UNIT, &bytenum) && known_eq (bitsize, GET_MODE_BITSIZE (mode)) && lowpart_bit_field_p (bitnum, bitsize, op0_mode) - && TRULY_NOOP_TRUNCATION_MODES_P (mode, op0_mode)) + && (known_lt (GET_MODE_SIZE (mode), GET_MODE_SIZE (op0_mode)) + ? TRULY_NOOP_TRUNCATION_MODES_P (mode, op0_mode) + : known_eq (GET_MODE_SIZE (mode), GET_MODE_SIZE (op0_mode)))) return simplify_gen_subreg (mode, op0, op0_mode, bytenum); return NULL_RTX; } diff --git a/gcc/optabs-query.cc b/gcc/optabs-query.cc index 947ccef..f33253f 100644 --- a/gcc/optabs-query.cc +++ b/gcc/optabs-query.cc @@ -213,7 +213,7 @@ get_best_extraction_insn (extraction_insn *insn, FOR_EACH_MODE_FROM (mode_iter, mode) { mode = mode_iter.require (); - if (maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (field_mode)) + if (maybe_ge (GET_MODE_SIZE (mode), GET_MODE_SIZE (field_mode)) || TRULY_NOOP_TRUNCATION_MODES_P (insn->field_mode, field_mode)) break; diff --git a/gcc/optabs.cc b/gcc/optabs.cc index 6a34276..fad0d59 100644 --- a/gcc/optabs.cc +++ b/gcc/optabs.cc @@ -2954,7 +2954,11 @@ expand_parity (scalar_int_mode mode, rtx op0, rtx target) if (temp) { if (mclass != MODE_INT - || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode)) + || (known_lt (GET_MODE_SIZE (mode), + GET_MODE_SIZE (wider_mode)) + ? !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode) + : maybe_ne (GET_MODE_SIZE (mode), + GET_MODE_SIZE (wider_mode)))) return convert_to_mode (mode, temp, 0); else return gen_lowpart (mode, temp); diff --git a/gcc/rtlhooks.cc b/gcc/rtlhooks.cc index 989d3c9..9a53ab0 100644 --- a/gcc/rtlhooks.cc +++ b/gcc/rtlhooks.cc @@ -66,7 +66,9 @@ gen_lowpart_general (machine_mode mode, rtx x) scalar_int_mode xmode; if (is_a (GET_MODE (x), &xmode) && GET_MODE_SIZE (xmode) <= UNITS_PER_WORD - && TRULY_NOOP_TRUNCATION_MODES_P (mode, xmode) + && (known_lt (GET_MODE_SIZE (mode), GET_MODE_SIZE (xmode)) + ? TRULY_NOOP_TRUNCATION_MODES_P (mode, xmode) + : known_eq (GET_MODE_SIZE (mode), GET_MODE_SIZE (xmode))) && !reload_completed) return gen_lowpart_general (mode, force_reg (xmode, x)); diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index f3745d8..27518f5 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -617,7 +617,7 @@ simplify_context::simplify_truncation (machine_mode mode, rtx op, unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode); scalar_int_mode int_mode, int_op_mode, subreg_mode; - gcc_assert (precision <= op_precision); + gcc_assert (precision < op_precision); /* Optimize truncations of zero and sign extended values. */ if (GET_CODE (op) == ZERO_EXTEND @@ -1207,6 +1207,10 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode, break; case TRUNCATE: + /* Check for useless truncation. */ + if (GET_MODE (op) == mode) + return op; + /* Don't optimize (lshiftrt (mult ...)) as it would interfere with the umulXi3_highpart patterns. */ if (GET_CODE (op) == LSHIFTRT @@ -1271,9 +1275,6 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode, return temp; } - /* Check for useless truncation. */ - if (GET_MODE (op) == mode) - return op; break; case FLOAT_TRUNCATE: