From patchwork Tue Aug 4 19:56:44 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 140615 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 972124BB3BAF for ; Tue, 4 Aug 2026 19:57:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 972124BB3BAF Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Buwd8Nnb 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.133.124]) by sourceware.org (Postfix) with ESMTP id CB0E74BB24EF for ; Tue, 4 Aug 2026 19:56:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CB0E74BB24EF Authentication-Results: sourceware.org; dmarc=pass (p=quarantine 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 CB0E74BB24EF Authentication-Results: sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1785873418; cv=none; b=Umpd2qYThwhkRus3zwp1CMunkMOgAfUtYNL0lFuBRHxlSLwLcO20MeuKbDm0Cfx48GEZn96askGuRN4jvVDVFr7qOzRmBOYWEIk3UrhpyB6mdOQyXnwrry9dW+j7ASKv7kNugyI9jm/HNAzIOQjbav9u/FpFkSJZC0ijGPN30A4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1785873418; c=relaxed/simple; bh=KqhUvR4VFCE7TPdFFNlO/TWCvOoQuMwsyGRafaXY1CQ=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=W0E1U0mVkqLDhs229aeQ0mcw/W5ULchz4w9p6Vl1P/FVjC9xw/JKUyyBcs3JUMgJ+8zrpEH1P6W/m5J6d4axyjrDEYAm26wU+1GjKQeDddQ7aqEiJdsXVUzxBXrC6O4i9NKt7J+SJn8smqAP/0ue7E32y9u5HtTE+kAH2+ILIzM= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Buwd8Nnb DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CB0E74BB24EF DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1785873417; 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=J8zQz36tQJDQHbxvLJiuxgS+WiEyCSOuPKkvi6CmbOw=; b=Buwd8NnbRv7TEEdS613yYVyZ7WtbuJ9gQim3Hx26TU7RqvHORXi0LUPtnmPxzIqbttHKSm pXcK4AIWqg0KCBtVJ2NP5kjoMcd2diTV0X1OpiqJ6rOM67r/3GYaab+EOCrmlShKC6PjUF 75Bi/TwEESPfzYP1MzNCpvZ15xclbJE= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-686-OxuAHsI7Or2W7kbeETBDqg-1; Tue, 04 Aug 2026 15:56:54 -0400 X-MC-Unique: OxuAHsI7Or2W7kbeETBDqg-1 X-Mimecast-MFC-AGG-ID: OxuAHsI7Or2W7kbeETBDqg_1785873413 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (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 mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id F411F19560AB; Tue, 4 Aug 2026 19:56:52 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.44.48.80]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 73647180049F; Tue, 4 Aug 2026 19:56:52 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.18.1/8.18.1) with ESMTPS id 674Jun583000426 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 4 Aug 2026 21:56:49 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.18.1/8.18.1/Submit) id 674JujBX3000425; Tue, 4 Aug 2026 21:56:45 +0200 Date: Tue, 4 Aug 2026 21:56:44 +0200 From: Jakub Jelinek To: Richard Biener , Andrea Pinski Cc: gcc-patches@gcc.gnu.org, Jason Merrill Subject: [PATCH] fold-const, match.pd: Improve ptr_difference_const optimizations Message-ID: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: xHsQ4YhtaMG0OsX6VLLjnwN5uR-FKdQiWsX8hJkZDCY_1785873413 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-1.2 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, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, RCVD_IN_SBL_CSS, SPF_HELO_PASS, SPF_NONE, TXREP shortcircuit=no autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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~patchwork=sourceware.org@gcc.gnu.org Hi! As mentioned in https://gcc.gnu.org/pipermail/gcc-patches/2026-July/725438.html at least the /* Convert (T1)(X p+ Y) into ((T1)X p+ Y), for pointer type, when the new cast (T1)X will fold away. We assume that this happens when X itself is a cast. */ fold-const.cc (fold_unary) optimization is highly undesirable in the C++ FE (at least before the cp_fold_function/gimplification). In the above patch I've tried to disable some optimizations (and Jason suggested to disable them even slightly less), but still that can at least in theory (but with the above patch in practice too) result in regressions, in particular in POINTER_DIFF_EXPR constant evaluation. In that testcase, we end up with (((((int*)(& x)) + 12) - (((int*)(& x)) + 4)) / 4) and the current ptr_difference_const match.pd optimizations aren't prepared to handle that. The following patch fixes that by adding STRIP_NOPS (exp); to split_address_to_core_and_offset which ptr_difference_const uses and then just throwing some ADDR_EXPR requirements in the simplification patterns - ptr_difference_const will return true if it is something it can handle, and it doesn't have to be just ADDR_EXPR, it can be also POINTER_PLUS_EXPR with constant offset, or nop conversions around either of those or nop conversions around first POINTER_PLUS_EXPR operand. In some cases after dropping the ADDR_EXPR parts I could throw away one pattern because two adjusted patterns were identical, in one case (minus with casts meant for subtraction of pointers cast to intptr_t/uintptr_t) I had to add another tree_nop_conversion_p check, so that e.g. floating point difference x - x which can't be folded away because it could trap isn't attempted to be folded (as build_int_cst for floating point would ICE). Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? And/or should I try even harder, handle not just SSA_NAME with ADDR_EXPR as def_stmt, but also with nop conversions or POINTER_PLUS, and in case of pointer plus perhaps even recurse and add the two bitpos/offsets together? 2026-08-04 Jakub Jelinek * fold-const.cc (split_address_to_core_and_offset): Use STRIP_NOPS. * match.pd ((&a + b) !=/== (&a[1] + c) -> (&a[0] - &a[1]) + b !=/== c): Don't require captures to be ADDR_EXPR. ((&a+b) - (&a[1] + c) -> sizeof(a[0]) + (b - c)): Likewise. ((p + b) - &p->d -> offsetof (*p, d) + b): Likewise. (Try folding difference of addresses): Likewise. Remove redundant simplifications because of that. Jakub --- gcc/fold-const.cc.jj 2026-07-26 15:37:03.625407289 +0200 +++ gcc/fold-const.cc 2026-08-04 16:06:17.012862597 +0200 @@ -16166,6 +16166,8 @@ split_address_to_core_and_offset (tree e poly_int64 bitsize; location_t loc = EXPR_LOCATION (exp); + STRIP_NOPS (exp); + if (TREE_CODE (exp) == SSA_NAME) if (gassign *def = dyn_cast (SSA_NAME_DEF_STMT (exp))) if (gimple_assign_rhs_code (def) == ADDR_EXPR) --- gcc/match.pd.jj 2026-08-04 10:27:31.000000000 +0200 +++ gcc/match.pd 2026-08-04 18:14:02.108482282 +0200 @@ -3089,12 +3089,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* (&a + b) !=/== (&a[1] + c) -> (&a[0] - &a[1]) + b !=/== c */ (for neeq (ne eq) (simplify - (neeq:c (pointer_plus @2 @3) ADDR_EXPR@0) + (neeq:c (pointer_plus @2 @3) @0) (with { poly_int64 diff; tree inner_type = TREE_TYPE (@3);} (if (ptr_difference_const (@0, @2, &diff)) (neeq { build_int_cst_type (inner_type, diff); } @3)))) (simplify - (neeq (pointer_plus ADDR_EXPR@0 @1) (pointer_plus ADDR_EXPR@2 @3)) + (neeq (pointer_plus @0 @1) (pointer_plus @2 @3)) (with { poly_int64 diff; tree inner_type = TREE_TYPE (@1);} (if (ptr_difference_const (@0, @2, &diff)) (neeq (plus { build_int_cst_type (inner_type, diff); } @1) @3))))) @@ -3310,38 +3310,29 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Try folding difference of addresses. */ (simplify - (minus (convert ADDR_EXPR@0) (convert (pointer_plus @1 @2))) - (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) + (minus (convert @0) (convert (pointer_plus @1 @2))) + (if (tree_nop_conversion_p (type, TREE_TYPE (@0)) + && tree_nop_conversion_p (type, TREE_TYPE (@1))) (with { poly_int64 diff; } (if (ptr_difference_const (@0, @1, &diff)) (minus { build_int_cst_type (type, diff); } (convert @2)))))) (simplify - (minus (convert (pointer_plus @0 @2)) (convert ADDR_EXPR@1)) - (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) + (minus (convert (pointer_plus @0 @2)) (convert @1)) + (if (tree_nop_conversion_p (type, TREE_TYPE (@0)) + && tree_nop_conversion_p (type, TREE_TYPE (@1))) (with { poly_int64 diff; } (if (ptr_difference_const (@0, @1, &diff)) (plus (convert @2) { build_int_cst_type (type, diff); }))))) (simplify - (minus (convert ADDR_EXPR@0) (convert @1)) - (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) + (minus (convert @0) (convert @1)) + (if (tree_nop_conversion_p (type, TREE_TYPE (@0)) + && tree_nop_conversion_p (type, TREE_TYPE (@1)) + && tree_nop_conversion_p (type, ptr_type_node)) (with { poly_int64 diff; } (if (ptr_difference_const (@0, @1, &diff)) { build_int_cst_type (type, diff); })))) (simplify - (minus (convert @0) (convert ADDR_EXPR@1)) - (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) - (with { poly_int64 diff; } - (if (ptr_difference_const (@0, @1, &diff)) - { build_int_cst_type (type, diff); })))) -(simplify - (pointer_diff (convert?@2 ADDR_EXPR@0) (convert1?@3 @1)) - (if (tree_nop_conversion_p (TREE_TYPE(@2), TREE_TYPE (@0)) - && tree_nop_conversion_p (TREE_TYPE(@3), TREE_TYPE (@1))) - (with { poly_int64 diff; } - (if (ptr_difference_const (@0, @1, &diff)) - { build_int_cst_type (type, diff); })))) -(simplify - (pointer_diff (convert?@2 @0) (convert1?@3 ADDR_EXPR@1)) + (pointer_diff (convert?@2 @0) (convert1?@3 @1)) (if (tree_nop_conversion_p (TREE_TYPE(@2), TREE_TYPE (@0)) && tree_nop_conversion_p (TREE_TYPE(@3), TREE_TYPE (@1))) (with { poly_int64 diff; } @@ -3350,18 +3341,18 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* (&a+b) - (&a[1] + c) -> sizeof(a[0]) + (b - c) */ (simplify - (pointer_diff (pointer_plus ADDR_EXPR@0 @1) (pointer_plus ADDR_EXPR@2 @3)) + (pointer_diff (pointer_plus @0 @1) (pointer_plus @2 @3)) (with { poly_int64 diff; } (if (ptr_difference_const (@0, @2, &diff)) (plus { build_int_cst_type (type, diff); } (convert (minus @1 @3)))))) /* (p + b) - &p->d -> offsetof (*p, d) + b */ (simplify - (pointer_diff (pointer_plus @0 @1) ADDR_EXPR@2) + (pointer_diff (pointer_plus @0 @1) @2) (with { poly_int64 diff; } (if (ptr_difference_const (@0, @2, &diff)) (plus { build_int_cst_type (type, diff); } (convert @1))))) (simplify - (pointer_diff ADDR_EXPR@0 (pointer_plus @1 @2)) + (pointer_diff @0 (pointer_plus @1 @2)) (with { poly_int64 diff; } (if (ptr_difference_const (@0, @1, &diff)) (minus { build_int_cst_type (type, diff); } (convert @2)))))