From patchwork Fri May 24 12:34:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 1938975 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=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 4Vm4Hm2n9fz1ynR for ; Fri, 24 May 2024 22:35:00 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 978213870857 for ; Fri, 24 May 2024 12:34:58 +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 94F5B386D607 for ; Fri, 24 May 2024 12:34:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 94F5B386D607 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 94F5B386D607 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=1716554077; cv=none; b=KxTGugQ0q2PxsgnITx/WPcHFQUa3XI5tveCu1SfiZuBYmMH+oPuBwlLk4NpRPG+Y7EdurJBYfsolNfLp5ksN7XShfH0eaJMIBocdp3lacIqUazS4oMQAz9M8bEM489DFd7EgZ9IGFGjCyBOKCS6NKVfBQ+4+w5/uYZs1qctsahc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716554077; c=relaxed/simple; bh=NfyGYbnCDRUw/x09UQIu6NjWptWI1nVx1lGur4DEK7E=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=pDdoQZKF+dnmdqs1KY8gQ37e/mwoNrtwqQfOkR60A8d/vp2rGX1UwEO0Yla0sFibGOEAAhQuevNDY0Fyls9p/OtV3Ha1mf2bR8cOgW2c2Byo7fTBv2BUNqgbEszxMm2cSY5e7tzlCC6WpPnA8F9sZGY90T9CfC+NNJq0oYmvGec= 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 5330D339 for ; Fri, 24 May 2024 05:34:58 -0700 (PDT) Received: from localhost (e121540-lin.manchester.arm.com [10.32.110.72]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id DE5FD3F641 for ; Fri, 24 May 2024 05:34:33 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [PATCH] vect: Fix access size alignment assumption [PR115192] Date: Fri, 24 May 2024 13:34:32 +0100 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) MIME-Version: 1.0 X-Spam-Status: No, score=-20.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, 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 create_intersect_range_checks checks whether two access ranges a and b are alias-free using something equivalent to: end_a <= start_b || end_b <= start_a It has two ways of doing this: a "vanilla" way that calculates the exact exclusive end pointers, and another way that uses the last inclusive aligned pointers (and changes the comparisons accordingly). The comment for the latter is: /* Calculate the minimum alignment shared by all four pointers, then arrange for this alignment to be subtracted from the exclusive maximum values to get inclusive maximum values. This "- min_align" is cumulative with a "+ access_size" in the calculation of the maximum values. In the best (and common) case, the two cancel each other out, leaving us with an inclusive bound based only on seg_len. In the worst case we're simply adding a smaller number than before. The problem is that the associated code implicitly assumed that the access size was a multiple of the pointer alignment, and so the alignment could be carried over to the exclusive end pointer. The testcase started failing after g:9fa5b473b5b8e289b6542 because that commit improved the alignment information for the accesses. Tested on aarch64-linux-gnu & x86_64-linux-gnu. OK for trunk and backports? Richard gcc/ PR tree-optimization/115192 * tree-data-ref.cc (create_intersect_range_checks): Take the alignment of the access sizes into account. gcc/testsuite/ PR tree-optimization/115192 * gcc.dg/vect/pr115192.c: New test. --- gcc/testsuite/gcc.dg/vect/pr115192.c | 28 ++++++++++++++++++++++++++++ gcc/tree-data-ref.cc | 5 ++++- 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr115192.c diff --git a/gcc/testsuite/gcc.dg/vect/pr115192.c b/gcc/testsuite/gcc.dg/vect/pr115192.c new file mode 100644 index 00000000000..923d377c1bb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr115192.c @@ -0,0 +1,28 @@ +#include "tree-vect.h" + +int data[4 * 16 * 16] __attribute__((aligned(16))); + +__attribute__((noipa)) void +foo (__SIZE_TYPE__ n) +{ + for (__SIZE_TYPE__ i = 1; i < n; ++i) + { + data[i * n * 4] = data[(i - 1) * n * 4] + 1; + data[i * n * 4 + 1] = data[(i - 1) * n * 4 + 1] + 2; + } +} + +int +main () +{ + check_vect (); + + data[0] = 10; + data[1] = 20; + + foo (3); + + if (data[24] != 12 || data[25] != 24) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-data-ref.cc b/gcc/tree-data-ref.cc index db15ddb43de..7c4049faf34 100644 --- a/gcc/tree-data-ref.cc +++ b/gcc/tree-data-ref.cc @@ -73,6 +73,7 @@ along with GCC; see the file COPYING3. If not see */ +#define INCLUDE_ALGORITHM #include "config.h" #include "system.h" #include "coretypes.h" @@ -2640,7 +2641,9 @@ create_intersect_range_checks (class loop *loop, tree *cond_expr, Because the maximum values are inclusive, there is an alias if the maximum value of one segment is equal to the minimum value of the other. */ - min_align = MIN (dr_a.align, dr_b.align); + min_align = std::min (dr_a.align, dr_b.align); + min_align = std::min (min_align, known_alignment (dr_a.access_size)); + min_align = std::min (min_align, known_alignment (dr_b.access_size)); cmp_code = LT_EXPR; }