From patchwork Tue Mar 5 07:07:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 1908035 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=i9tctiZV; 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 4Tpmpx0Qz2z23qm for ; Tue, 5 Mar 2024 18:07:35 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9AD8D3858414 for ; Tue, 5 Mar 2024 07:07:33 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id C990B3858C55 for ; Tue, 5 Mar 2024 07:07:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C990B3858C55 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org C990B3858C55 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1709622439; cv=none; b=g8dSXtM3y1IuNzYVnICtslacT80s4SwfOOYKPhR1jlKIxKbpR+i9W6Rs+ZvWN2FPd7sNMT/SJDmCCfsa5D5TQZPk0AUNsPDEFyCsfe1itp9CHow4kad7KBuHsJ2GTRHkFDux6/IAbc9LV3NmxmizPxPETKxew48N5UErDBsn96E= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1709622439; c=relaxed/simple; bh=D/9duuoOLosbep+XDDBE1Zv2Dy6UEbVpA0Dj+3l5mAw=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=gGddQc2AFc8PsDWX8fzqVBXQRykHp1XMImFTRQHP5bJeLzBmOGkjuCRxwRRVLfCVqeS6Hx2fpYWlmIGiEEFN18Q/qoOjKQh1hLHM7STWuFPYjO8jvzkhrTnywxaaCiDv+XiscwDDwnKwY/BfT8ZVZ5O5lutUE4OUIveyvxOQt2o= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1709622436; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type; bh=Dw7yzX4J/fFIBsAEUfGwRXe3wDY1vmQBXfrLQc1S7Sc=; b=i9tctiZVoDVfvi4AUVn/ms6O2FDLieGRI7esKblz+wsRKDuitVkWS04RIu00UiakUT4UBz 9BlCy1tFOtBSJ/+s7DX0oJDMJi1RVMndDPM3o8yTzYF9wv1nDrDq6G1RMq9n2SRVf8wmy5 5durpvh7qoYf4Aysgt0YTdhGwe3Mi/M= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-331-qF6Q8r11O1-Um8sT860MdA-1; Tue, 05 Mar 2024 02:07:14 -0500 X-MC-Unique: qF6Q8r11O1-Um8sT860MdA-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 3DE7E80F7E3; Tue, 5 Mar 2024 07:07:14 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.45.226.25]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 039972166B31; Tue, 5 Mar 2024 07:07:13 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 42577B3N508730 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 5 Mar 2024 08:07:12 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 42577Bws508729; Tue, 5 Mar 2024 08:07:11 +0100 Date: Tue, 5 Mar 2024 08:07:11 +0100 From: Jakub Jelinek To: Richard Biener Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] bitint: Handle BIT_FIELD_REF lowering [PR114157] Message-ID: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.6 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-3.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, 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: , Reply-To: Jakub Jelinek Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Hi! The following patch adds support for BIT_FIELD_REF lowering with large/huge _BitInt lhs. BIT_FIELD_REF requires mode argument first operand, so the operand shouldn't be any huge _BitInt. If we only access limbs from inside of BIT_FIELD_REF using constant indexes, we can just create a new BIT_FIELD_REF to extract the limb, but if we need to use variable index in a loop, I'm afraid we need to spill it into memory, which is what the following patch does. If there is some bitwise type for the extraction, it extracts just what we need and not more than that, otherwise it spills the whole first argument of BIT_FIELD_REF and uses MEM_REF with an offset with VIEW_CONVERT_EXPR around it. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2024-03-05 Jakub Jelinek PR middle-end/114157 * gimple-lower-bitint.cc: Include stor-layout.h. (mergeable_op): Return true for BIT_FIELD_REF. (struct bitint_large_huge): Declare handle_bit_field_ref method. (bitint_large_huge::handle_bit_field_ref): New method. (bitint_large_huge::handle_stmt): Use it for BIT_FIELD_REF. * gcc.dg/bitint-98.c: New test. * gcc.target/i386/avx2-pr114157.c: New test. * gcc.target/i386/avx512f-pr114157.c: New test. Jakub --- gcc/gimple-lower-bitint.cc.jj 2024-03-04 11:14:57.450288563 +0100 +++ gcc/gimple-lower-bitint.cc 2024-03-04 18:51:06.833008534 +0100 @@ -54,6 +54,7 @@ along with GCC; see the file COPYING3. #include "tree-cfgcleanup.h" #include "tree-switch-conversion.h" #include "ubsan.h" +#include "stor-layout.h" #include "gimple-lower-bitint.h" /* Split BITINT_TYPE precisions in 4 categories. Small _BitInt, where @@ -212,6 +213,7 @@ mergeable_op (gimple *stmt) case BIT_NOT_EXPR: case SSA_NAME: case INTEGER_CST: + case BIT_FIELD_REF: return true; case LSHIFT_EXPR: { @@ -435,6 +437,7 @@ struct bitint_large_huge tree handle_plus_minus (tree_code, tree, tree, tree); tree handle_lshift (tree, tree, tree); tree handle_cast (tree, tree, tree); + tree handle_bit_field_ref (tree, tree); tree handle_load (gimple *, tree); tree handle_stmt (gimple *, tree); tree handle_operand_addr (tree, gimple *, int *, int *); @@ -1685,6 +1688,86 @@ bitint_large_huge::handle_cast (tree lhs return NULL_TREE; } +/* Helper function for handle_stmt method, handle a BIT_FIELD_REF. */ + +tree +bitint_large_huge::handle_bit_field_ref (tree op, tree idx) +{ + if (tree_fits_uhwi_p (idx)) + { + if (m_first) + m_data.safe_push (NULL); + ++m_data_cnt; + unsigned HOST_WIDE_INT sz = tree_to_uhwi (TYPE_SIZE (m_limb_type)); + tree bfr = build3 (BIT_FIELD_REF, m_limb_type, + TREE_OPERAND (op, 0), + TYPE_SIZE (m_limb_type), + size_binop (PLUS_EXPR, TREE_OPERAND (op, 2), + bitsize_int (tree_to_uhwi (idx) * sz))); + tree r = make_ssa_name (m_limb_type); + gimple *g = gimple_build_assign (r, bfr); + insert_before (g); + tree type = limb_access_type (TREE_TYPE (op), idx); + if (!useless_type_conversion_p (type, m_limb_type)) + r = add_cast (type, r); + return r; + } + tree var; + if (m_first) + { + unsigned HOST_WIDE_INT sz = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (op))); + machine_mode mode; + tree type, bfr; + if (bitwise_mode_for_size (sz).exists (&mode) + && known_eq (GET_MODE_BITSIZE (mode), sz)) + type = bitwise_type_for_mode (mode); + else + { + mode = VOIDmode; + type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (op, 0))); + } + if (TYPE_ALIGN (type) < TYPE_ALIGN (TREE_TYPE (op))) + type = build_aligned_type (type, TYPE_ALIGN (TREE_TYPE (op))); + var = create_tmp_var (type); + TREE_ADDRESSABLE (var) = 1; + gimple *g; + if (mode != VOIDmode) + { + bfr = build3 (BIT_FIELD_REF, type, TREE_OPERAND (op, 0), + TYPE_SIZE (type), TREE_OPERAND (op, 2)); + g = gimple_build_assign (make_ssa_name (type), + BIT_FIELD_REF, bfr); + gimple_set_location (g, m_loc); + gsi_insert_after (&m_init_gsi, g, GSI_NEW_STMT); + bfr = gimple_assign_lhs (g); + } + else + bfr = TREE_OPERAND (op, 0); + g = gimple_build_assign (var, bfr); + gimple_set_location (g, m_loc); + gsi_insert_after (&m_init_gsi, g, GSI_NEW_STMT); + if (mode == VOIDmode) + { + unsigned HOST_WIDE_INT nelts + = CEIL (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (op))), limb_prec); + tree atype = build_array_type_nelts (m_limb_type, nelts); + var = build2 (MEM_REF, atype, build_fold_addr_expr (var), + build_int_cst (build_pointer_type (type), + tree_to_uhwi (TREE_OPERAND (op, 2)) + / BITS_PER_UNIT)); + } + m_data.safe_push (var); + } + else + var = unshare_expr (m_data[m_data_cnt]); + ++m_data_cnt; + var = limb_access (TREE_TYPE (op), var, idx, false); + tree r = make_ssa_name (m_limb_type); + gimple *g = gimple_build_assign (r, var); + insert_before (g); + return r; +} + /* Add a new EH edge from SRC to EH_EDGE->dest, where EH_EDGE is an older EH edge, and except for virtual PHIs duplicate the PHI argument from the EH_EDGE to the new EH edge. */ @@ -2019,6 +2102,8 @@ bitint_large_huge::handle_stmt (gimple * return handle_cast (TREE_TYPE (gimple_assign_lhs (stmt)), TREE_OPERAND (gimple_assign_rhs1 (stmt), 0), idx); + case BIT_FIELD_REF: + return handle_bit_field_ref (gimple_assign_rhs1 (stmt), idx); default: break; } --- gcc/testsuite/gcc.dg/bitint-98.c.jj 2024-03-04 19:11:46.355244244 +0100 +++ gcc/testsuite/gcc.dg/bitint-98.c 2024-03-04 19:10:35.139207685 +0100 @@ -0,0 +1,50 @@ +/* PR middle-end/114157 */ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-O2 -std=c23 -Wno-psabi -w" } */ + +#if __BITINT_MAXWIDTH__ >= 256 +_BitInt(256) d; +_BitInt(255) e; + +void +foo (long __attribute__((vector_size (64))) s) +{ + __builtin_memmove (&d, &s, sizeof (d)); +} + +void +bar (_BitInt(512) x) +{ + long __attribute__((vector_size (64))) s; + __builtin_memcpy (&s, &x, sizeof (s)); + __builtin_memcpy (&d, &s, sizeof (d)); +} + +void +baz (long __attribute__((vector_size (64))) s) +{ + _BitInt(256) d; + __builtin_memmove (&d, &s, sizeof (d)); + e = d; +} + +void +qux (long __attribute__((vector_size (64))) s) +{ + _BitInt(192) d; + __builtin_memmove (&d, &s, sizeof (d)); + e = d; +} +#else +int i; +#endif + +#if __BITINT_MAXWIDTH__ >= 1024 +_BitInt(512) +corge (long __attribute__((vector_size (1024))) s) +{ + _BitInt(512) d; + __builtin_memcpy (&d, &s, sizeof (d)); + return d; +} +#endif --- gcc/testsuite/gcc.target/i386/avx2-pr114157.c.jj 2024-03-04 19:12:46.001437331 +0100 +++ gcc/testsuite/gcc.target/i386/avx2-pr114157.c 2024-03-04 19:12:31.639631618 +0100 @@ -0,0 +1,5 @@ +/* PR middle-end/114157 */ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-O2 -std=c23 -Wno-psabi -w -mavx2 -mno-avx512f" } */ + +#include "../../gcc.dg/bitint-98.c" --- gcc/testsuite/gcc.target/i386/avx512f-pr114157.c.jj 2024-03-04 19:13:01.190231847 +0100 +++ gcc/testsuite/gcc.target/i386/avx512f-pr114157.c 2024-03-04 19:13:12.018085362 +0100 @@ -0,0 +1,5 @@ +/* PR middle-end/114157 */ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-O2 -std=c23 -Wno-psabi -w -mavx512f" } */ + +#include "../../gcc.dg/bitint-98.c"