From patchwork Fri Jan 10 06:28:50 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Oliva X-Patchwork-Id: 104450 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 01AFD3858C33 for ; Fri, 10 Jan 2025 06:29:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 01AFD3858C33 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, secure) header.d=adacore.com header.i=@adacore.com header.a=rsa-sha256 header.s=google header.b=PGi0dBOD X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-vk1-xa2a.google.com (mail-vk1-xa2a.google.com [IPv6:2607:f8b0:4864:20::a2a]) by sourceware.org (Postfix) with ESMTPS id 3341A3858D20 for ; Fri, 10 Jan 2025 06:29:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3341A3858D20 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=adacore.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 3341A3858D20 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::a2a ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1736490545; cv=none; b=Eoyh6Z37CkmxfU8rEqwdVsPUveODLXK6Z6dCxdkJVw4+0S292OiXorv/otnBQ/x4OoqbPDTf7YTajff0LdNMbbSkfoINbPC407XB7Q5EEZZtzAOUCLPxBYOvJVRybjo/WOtg6CkX4UkXXdGQV0SuOW/fkjGbwGLw7q7QQog0yws= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1736490545; c=relaxed/simple; bh=u0hq2Q59QgaoAvUmFhNlkmDCprhXN2m4kOpox20h03M=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=eXebmCbEaIDUTCdwPH+RUnQbOQvuTV8EPVo26CSDGRB9VXBoYPcak3QqX2J5tMcFRvM4dol+nDLtJgIMVgC42RCt5z3RCzCvzN5EuC/ewg+kIYBdH/DAPRUtj8M5/KzNWLnPYWWazLG0mHO6nTU2BjR4dSQ5UW/2V4Ce2g/k+BQ= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3341A3858D20 Received: by mail-vk1-xa2a.google.com with SMTP id 71dfb90a1353d-5188b485988so597326e0c.3 for ; Thu, 09 Jan 2025 22:29:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=adacore.com; s=google; t=1736490544; x=1737095344; darn=gcc.gnu.org; h=mime-version:user-agent:message-id:date:organization:subject:cc:to :from:from:to:cc:subject:date:message-id:reply-to; bh=mKEbgZN0aDZ2UxUxadQabvBY9z2K2DN/CbnfOPLodr0=; b=PGi0dBOD8/S6mV7zbsqY0SHp2TLkZnz2BHKPvMd3Ti3D3UNnsPjvOUPNHgSHYRTvEu UtUq+SvQdVPSeFwr1yzwfxWmdMvPI1aEmnEA53cH2JKZPC+1dOuic39W8wv6vlOTxxNQ HItW2MnhVV4OjFekVzlx4MnQOr8Xgs5KvWNh3LShYRqdYddxKgf6C+luA33A4qaG/pL9 uokeK8Xt1+rTuTNrr+owSStmhAzloiV3YICszfM0j/wooHjxVn5xBE8A1RYYhsXcUsLx 81W8oDzAuiCOdrdAfIMFCcAaFzKkc5QAbD9TK5Gj9HA6hqZlKPJwinU3nhQK+hb2+Iiu 9fWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1736490544; x=1737095344; h=mime-version:user-agent:message-id:date:organization:subject:cc:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=mKEbgZN0aDZ2UxUxadQabvBY9z2K2DN/CbnfOPLodr0=; b=WiEhbhQx6plFRLSWt/PJXLHF0gla3k6xh9NFOlRBYbUIMTSfaNw6qV1D2NqFQtyVHK E5VhQNPiYHiPV2O3NG7jKCAhweUttstMQYfYt3lXqzSBBHXILnwuU/aI6dDMa91zKaKW aWBC7wMdV9GHyyU7Pl6ORlSgT7swNDa++3Cek570XuQMlxL4L6HCTM8c7ZyfaYLbkGic 5HLwTkcpd187nGqH04RZyg3qwJMnpeCxpM9/xHNyldNE/2wLVQG2YMo9TMqs6oOY8/L3 1Z+H2VJbml0Rn6+4LaqF8+gsT4p+QUDJm10MYH4IUmXmCyKbiw+fOYUekILGs8dSdhkV MNHQ== X-Gm-Message-State: AOJu0YxJs7jc575wkCN6MM4jNbvANdSFn3As9nH4aLXqW94X/hN+Z3xX eyLVCZA+4p0LwD+PMuhiwA3zvH2diTQ5UIcKc5AK2vW/bqtC3VrTqAz+5uSQY/ozf2HMm3Iy2yc = X-Gm-Gg: ASbGncv4oiL5wsnmSRZzCqrzpC7vIOIvvqYDTdrUlaPwXdJLDmjGWBocCuV/zvPO6nY SF7qsfSyeGJi56K7MIJVYZsUPYYHlDZZmBJr+Uk0y4nxyU/R+kzgV5K228zwZS/kWcDRLfAZU6P 37RSnGuw5mT413vpRb7ZdK1zye0oEKFbrXvfYqy+r0tyCx5dCN5YUwgdy7eNWNWL8TVldtBDK+n 0ByYBTjaGZQuSv2rkmXjK0l2P2e+96bhmv+Oyd4xmTgI6+5sSlf X-Google-Smtp-Source: AGHT+IFZzqMMiDFeDlyj2djIIVonTGCVtfrsGwac1mb0krKSX5KMCG6hSnNzg8xFfVrx72bUZpf1tA== X-Received: by 2002:a05:6122:1d14:b0:50b:e9a5:cd7b with SMTP id 71dfb90a1353d-51c6c50fa64mr8342603e0c.9.1736490544393; Thu, 09 Jan 2025 22:29:04 -0800 (PST) Received: from free.home ([2804:7f1:218b:ab6e:fda0:ed9c:e12e:80b7]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-51c7fb9bd76sm1734182e0c.11.2025.01.09.22.29.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jan 2025 22:29:03 -0800 (PST) Received: from livre (livre.home [172.31.160.2]) by free.home (8.15.2/8.15.2) with ESMTPS id 50A6SogE950935 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 10 Jan 2025 03:28:50 -0300 From: Alexandre Oliva To: gcc-patches@gcc.gnu.org Cc: jakub@redhat.com, rguenther@suse.de Subject: [PATCH] [ifcombine] adjust for narrowing converts before shifts [PR118206] Organization: Free thinker, does not speak for AdaCore Date: Fri, 10 Jan 2025 03:28:50 -0300 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, WEIRD_QUOTING 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~patchwork=sourceware.org@gcc.gnu.org A narrowing conversion and a shift both drop bits from the loaded value, but we need to take into account which one comes first to get the right number of bits and mask. Fold when applying masks to parts, comparing the parts, and combining the results, in the odd chance either mask happens to be zero. Regstrapped on x86_64-linux-gnu. Ok to intall? for gcc/ChangeLog PR tree-optimization/118206 * gimple-fold.cc (decode_field_reference): Account for upper bits dropped by narrowing conversions whether before or after a right shift. (fold_truth_andor_for_ifcombine): Fold masks, compares, and combined results. for gcc/testsuite/ChangeLog PR tree-optimization/118206 * gcc.dg/field-merge-18.c: New. --- gcc/gimple-fold.cc | 39 ++++++++++++++++++++++++---- gcc/testsuite/gcc.dg/field-merge-18.c | 46 +++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/field-merge-18.c diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index c8a726e0ae3f3..d95f04213ee40 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -7547,6 +7547,7 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, int shiftrt = 0; tree res_ops[2]; machine_mode mode; + bool convert_before_shift = false; *load = NULL; *psignbit = false; @@ -7651,6 +7652,12 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, if (*load) loc[3] = gimple_location (*load); exp = res_ops[0]; + /* This looks backwards, but we're going back the def chain, so if we + find the conversion here, after finding a shift, that's because the + convert appears before the shift, and we should thus adjust the bit + pos and size because of the shift after adjusting it due to type + conversion. */ + convert_before_shift = true; } /* Identify the load, if there is one. */ @@ -7693,6 +7700,15 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, *pvolatilep = volatilep; /* Adjust shifts... */ + if (convert_before_shift + && outer_type && *pbitsize > TYPE_PRECISION (outer_type)) + { + HOST_WIDE_INT excess = *pbitsize - TYPE_PRECISION (outer_type); + if (*preversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN) + *pbitpos += excess; + *pbitsize -= excess; + } + if (shiftrt) { if (!*preversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN) @@ -7701,7 +7717,8 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, } /* ... and bit position. */ - if (outer_type && *pbitsize > TYPE_PRECISION (outer_type)) + if (!convert_before_shift + && outer_type && *pbitsize > TYPE_PRECISION (outer_type)) { HOST_WIDE_INT excess = *pbitsize - TYPE_PRECISION (outer_type); if (*preversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN) @@ -8377,6 +8394,8 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, if (get_best_mode (end_bit - first_bit, first_bit, 0, ll_end_region, ll_align, BITS_PER_WORD, volatilep, &lnmode)) l_split_load = false; + /* ??? If ll and rl share the same load, reuse that? + See PR 118206 -> gcc.dg/field-merge-18.c */ else { /* Consider the possibility of recombining loads if any of the @@ -8757,11 +8776,11 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, /* Apply masks. */ for (int j = 0; j < 2; j++) if (mask[j] != wi::mask (0, true, mask[j].get_precision ())) - op[j] = build2_loc (locs[j][2], BIT_AND_EXPR, type, - op[j], wide_int_to_tree (type, mask[j])); + op[j] = fold_build2_loc (locs[j][2], BIT_AND_EXPR, type, + op[j], wide_int_to_tree (type, mask[j])); - cmp[i] = build2_loc (i ? rloc : lloc, wanted_code, truth_type, - op[0], op[1]); + cmp[i] = fold_build2_loc (i ? rloc : lloc, wanted_code, truth_type, + op[0], op[1]); } /* Reorder the compares if needed. */ @@ -8773,7 +8792,15 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree truth_type, if (parts == 1) result = cmp[0]; else if (!separatep || !maybe_separate) - result = build2_loc (rloc, orig_code, truth_type, cmp[0], cmp[1]); + { + /* Only fold if any of the cmp is known, otherwise we may lose the + sequence point, and that may prevent further optimizations. */ + if (TREE_CODE (cmp[0]) == INTEGER_CST + || TREE_CODE (cmp[1]) == INTEGER_CST) + result = fold_build2_loc (rloc, orig_code, truth_type, cmp[0], cmp[1]); + else + result = build2_loc (rloc, orig_code, truth_type, cmp[0], cmp[1]); + } else { result = cmp[0]; diff --git a/gcc/testsuite/gcc.dg/field-merge-18.c b/gcc/testsuite/gcc.dg/field-merge-18.c new file mode 100644 index 0000000000000..e8413873d2418 --- /dev/null +++ b/gcc/testsuite/gcc.dg/field-merge-18.c @@ -0,0 +1,46 @@ +/* { dg-do run } */ +/* { dg-options "-O1" } */ + +/* PR tree-optimization/118206 */ +/* Check that shifts, whether before or after narrowing conversions, mask out + the bits that are to be discarded. */ + +/* This only uses bits from the least significant byte in the short. */ +__attribute__((noipa)) int +foo (const void *x) +{ + unsigned short b; + __builtin_memcpy (&b, x, sizeof (short)); + if ((b & 15) != 8) + return 1; + if ((((unsigned char) b) >> 4) > 7) + return 1; + return 0; +} + +__attribute__((noipa)) int +bar (const void *x) +{ + unsigned short b; + __builtin_memcpy (&b, x, sizeof (short)); + if ((b & 15) != 8) + return 1; + if ((unsigned char)(b >> 4) > 7) + return 1; + return 0; +} + +int +main () +{ + unsigned short a = 0x78 - 0x80 - 0x80; + if (foo (&a) != 0 || bar (&a) != (a > 0xff)) + __builtin_abort (); + unsigned short b = 0x88; + if (foo (&b) != 1 || bar (&b) != 1) + __builtin_abort (); + unsigned short c = 8; + if (foo (&c) != 0 || bar (&c) != 0) + __builtin_abort (); + return 0; +}