From patchwork Sun Apr 10 22:44:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 52766 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 C47FA38342D1 for ; Sun, 10 Apr 2022 22:45:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C47FA38342D1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1649630705; bh=XQpfGDoPcUmO+f5HKEtPqgU9YGsgCUB0zaH2kgZLiYA=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=bPvUAuylKZie8i+1U55T8LGKDRSAzAN0fTwLmodzjF/pEY2fOpao9qEfGh8u+kWHk P0aSraR8YTtbEqR7luHodhO0DHeAiknDk+znU6pji+rz2OV11D2bSV+QjuqMDnKC7f I/DA4QmogOxV4sHgmPzb9tuk2e1ujBxcrBWQ7+rQ= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from nikam.ms.mff.cuni.cz (nikam.ms.mff.cuni.cz [195.113.20.16]) by sourceware.org (Postfix) with ESMTPS id 9CB533876290 for ; Sun, 10 Apr 2022 22:44:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9CB533876290 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id B039E280453; Mon, 11 Apr 2022 00:44:32 +0200 (CEST) Date: Mon, 11 Apr 2022 00:44:32 +0200 To: gcc-patches@gcc.gnu.org Subject: Avoid overflow in ipa-modref-tree.cc Message-ID: MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jan Hubicka via Gcc-patches From: Jan Hubicka Reply-To: Jan Hubicka Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi, the testcase triggers ICE since computation overflows on two accesses that are very far away d->b[-144115188075855873] and d->b[144678138029277184]. This patch makes the relevant part of modref to use poly_offset_int. It is kind of weird to store bit offsets into poly_int64 but it is what alias oracle does. There are some other places where computations are done that may overflow, I will fix them incrementally (it is not completely mechanical due to signed/unsigned info). Bootstrapped/regtested x86_64-linux. I plan to commit it tomorrow if there are no complains. gcc/ChangeLog: 2022-04-11 Jan Hubicka * ipa-modref-tree.cc (modref_access_node::closer_pair_p): Use poly_offset_int to avoid overflow. (modref_access_node::update2): Likewise. gcc/testsuite/ChangeLog: 2022-04-11 Jan Hubicka * gcc.c-torture/compile/103818.c: New test. diff --git a/gcc/ipa-modref-tree.cc b/gcc/ipa-modref-tree.cc index f19af8c2b55..44cb645954f 100644 --- a/gcc/ipa-modref-tree.cc +++ b/gcc/ipa-modref-tree.cc @@ -267,34 +267,42 @@ modref_access_node::closer_pair_p (const modref_access_node &a1, /* Now compute distance of the intervals. */ - poly_int64 dist1, dist2; + poly_offset_int dist1, dist2; if (known_le (offseta1, offsetb1)) { if (!known_size_p (a1.max_size)) dist1 = 0; else - dist1 = offsetb1 - offseta1 - a1.max_size; + dist1 = (poly_offset_int)offsetb1 + - (poly_offset_int)offseta1 + - (poly_offset_int)a1.max_size; } else { if (!known_size_p (b1.max_size)) dist1 = 0; else - dist1 = offseta1 - offsetb1 - b1.max_size; + dist1 = (poly_offset_int)offseta1 + - (poly_offset_int)offsetb1 + - (poly_offset_int)b1.max_size; } if (known_le (offseta2, offsetb2)) { if (!known_size_p (a2.max_size)) dist2 = 0; else - dist2 = offsetb2 - offseta2 - a2.max_size; + dist2 = (poly_offset_int)offsetb2 + - (poly_offset_int)offseta2 + - (poly_offset_int)a2.max_size; } else { if (!known_size_p (b2.max_size)) dist2 = 0; else - dist2 = offseta2 - offsetb2 - b2.max_size; + dist2 = offseta2 + - (poly_offset_int)offsetb2 + - (poly_offset_int)b2.max_size; } /* It may happen that intervals overlap in case size is different. Prefer the overlap to non-overlap. */ @@ -380,9 +388,16 @@ modref_access_node::update2 (poly_int64 parm_offset1, new_max_size = max_size2; else { - new_max_size = max_size2 + offset2 - offset1; - if (known_le (new_max_size, max_size1)) - new_max_size = max_size1; + poly_offset_int s = (poly_offset_int)max_size2 + + (poly_offset_int)offset2 + - (poly_offset_int)offset1; + if (s.to_shwi (&new_max_size)) + { + if (known_le (new_max_size, max_size1)) + new_max_size = max_size1; + } + else + new_max_size = -1; } update (parm_offset1, offset1, diff --git a/gcc/testsuite/gcc.c-torture/compile/103818.c b/gcc/testsuite/gcc.c-torture/compile/103818.c new file mode 100644 index 00000000000..8a0148e243a --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/103818.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target lp64 } } */ +struct a { + int b[0]; +} c(struct a *d) { + d->b[0] = d->b[-144115188075855873] + d->b[11] * d->b[2] + + d->b[0] % d->b[1025] + d->b[5]; + d->b[0] = + d->b[144678138029277184] + d->b[0] & d->b[-3] * d->b[053] + d->b[7] ^ + d->b[-9] + d->b[14] + d->b[9] % d->b[49] + d->b[024] + d->b[82] & + d->b[4096]; +} +void main() {}