From patchwork Fri Jun 16 12:34:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 109089 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp1308549vqr; Fri, 16 Jun 2023 05:35:25 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ4AAQGWUipQ1znmhdmrAkHHVXdAL4pSfrLQkOm3Ikind7qHhM4LabaVd0hp2q4mgB6xWp5C X-Received: by 2002:a17:907:9801:b0:96a:246b:c65d with SMTP id ji1-20020a170907980100b0096a246bc65dmr2240769ejc.12.1686918925013; Fri, 16 Jun 2023 05:35:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686918924; cv=none; d=google.com; s=arc-20160816; b=gonKF6/Ym3OgS/DppLmiU5x/MKeA6mwunMviUPiBku+sIyt9+sL/CXTY41WKneDfmt ia1jAjYJzJCGsbt9PoXc3PCAlydkeT2+mLD7mq/gPhc3ABY0xRWabfMsTivB5vJar5ix K4hKkO4byyF3h4aHWwt9pBOk6fCrSPh/PCe8XpjYsk1ACfxKdj4xaUYSUwNgWyv3kp0P nEd2W9qy8QDwWhGyMr9GcRgxDwTjvPo/u+IUPD/QlIIvY18HYSR/eEZsHW3TFB1kNZXE GzFL9rROVZWJGWeqNBn08TFzs38QLB56oIgVkvonkTnx57yYAybXadOtGtG7TCgS9Zvo s3ww== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:message-id :mime-version:subject:cc:to:date:dmarc-filter:delivered-to :dkim-signature:dkim-filter; bh=PF3EugdzzL4ylQQGVrH+ONVaBuRnRIBSsEOo1mpB3kI=; b=JwQTRTWMPm39etRZyKesLajFayaLfE6y3iTU3ruFhxlWw6oKsnfJahsA1frpoGjDAN rfjyy84pve4gWSraou6btmegUmkd3ikKSwV09ap2EWeC3NGpuGpLED3dQ8HOJsDEsL6X mMzRfPI4/59yXzgEblCrSQv7LvERJyA7FUSfeAPnLEbA6u9THKSj76CdGA7ye/zMsA9W 5KN2LyBw6qFLy2Lj0XyI3KEVZNEwNuMWoDIr8ozLtR41k0Kb9TrFCOzjfxmIiB00O7P5 XAs+qTECAaXzb4vTxMBReT3cO0QqGiGgGvf9NJhX1qVDqySPngROndAaf76uqL/4FyU/ IRgQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=X8zjDoet; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id kq4-20020a170906abc400b009537bb2188fsi10911659ejb.693.2023.06.16.05.35.24 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Jun 2023 05:35:24 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=X8zjDoet; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 724A43857728 for ; Fri, 16 Jun 2023 12:35:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 724A43857728 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1686918908; bh=PF3EugdzzL4ylQQGVrH+ONVaBuRnRIBSsEOo1mpB3kI=; h=Date:To:cc:Subject:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=X8zjDoetB6VRXHyMc+TtHlSVooLVvWDn5kPpFdwc6FC19Rgz4LpPVhquQyYXWWeW+ tdzhNqObx/m7jW8DMLErolrer2uFJElZ2DrqCzL6Rpe5TDR5Grs1nWKAf0wEBNfPGM uI29du1mCWQZQT9Jw1lXfr6Qd2Mhv9rDPn3WVVMA= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by sourceware.org (Postfix) with ESMTPS id A0BC43858284 for ; Fri, 16 Jun 2023 12:34:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A0BC43858284 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id C9A6A1F88C; Fri, 16 Jun 2023 12:34:24 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id B38AC1330B; Fri, 16 Jun 2023 12:34:24 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id KyqhKtBWjGQoLAAAMHmgww (envelope-from ); Fri, 16 Jun 2023 12:34:24 +0000 Date: Fri, 16 Jun 2023 14:34:24 +0200 (CEST) To: gcc-patches@gcc.gnu.org cc: richard.sandiford@arm.com Subject: [PATCH] tree-optimization/110243 - kill off IVOPTs split_offset MIME-Version: 1.0 Message-Id: <20230616123424.B38AC1330B@imap2.suse-dmz.suse.de> X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Richard Biener via Gcc-patches From: Richard Biener Reply-To: Richard Biener Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1768862698857935486?= X-GMAIL-MSGID: =?utf-8?q?1768862698857935486?= IVOPTs has strip_offset which suffers from the same issues regarding integer overflow that split_constant_offset did but the latter was fixed quite some time ago. The following implements strip_offset in terms of split_constant_offset, removing the redundant and incorrect implementation. The implementations are not exactly the same, strip_offset relies on ptrdiff_tree_p to fend off too large offsets while split_constant_offset simply assumes those do not happen and truncates them. By the same means strip_offset also handles POLY_INT_CSTs but split_constant_offset does not. Massaging the latter to behave like strip_offset in those cases might be the way to go? Bootstrapped and tested on x86_64-unknown-linux-gnu. Comments? Thanks, Richard. PR tree-optimization/110243 * tree-ssa-loop-ivopts.cc (strip_offset_1): Remove. (strip_offset): Make it a wrapper around split_constant_offset. * gcc.dg/torture/pr110243.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr110243.c | 22 +++ gcc/tree-ssa-loop-ivopts.cc | 182 ++---------------------- 2 files changed, 32 insertions(+), 172 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr110243.c diff --git a/gcc/testsuite/gcc.dg/torture/pr110243.c b/gcc/testsuite/gcc.dg/torture/pr110243.c new file mode 100644 index 00000000000..07dffd95d4d --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr110243.c @@ -0,0 +1,22 @@ +/* { dg-do run } */ +/* { dg-require-effective-target lp64 } */ + +#define X 1100000000 +unsigned char a; +long b = X; +int c[9][1]; +unsigned d; +static long *e = &b, *f = &b; +int g() { + if (a && a <= '9') + return '0'; + if (a) + return 10; + return -1; +} +int main() { + d = 0; + for (; (int)*f -(X-1) + d < 9; d++) + c[g() + (int)*f + ((int)*e - X) -(X-1) + d] + [0] = 0; +} diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc index 6fbd2d59318..a03764072a4 100644 --- a/gcc/tree-ssa-loop-ivopts.cc +++ b/gcc/tree-ssa-loop-ivopts.cc @@ -2772,183 +2772,21 @@ find_interesting_uses (struct ivopts_data *data, basic_block *body) } } -/* Strips constant offsets from EXPR and stores them to OFFSET. If INSIDE_ADDR - is true, assume we are inside an address. If TOP_COMPREF is true, assume - we are at the top-level of the processed address. */ - -static tree -strip_offset_1 (tree expr, bool inside_addr, bool top_compref, - poly_int64 *offset) -{ - tree op0 = NULL_TREE, op1 = NULL_TREE, tmp, step; - enum tree_code code; - tree type, orig_type = TREE_TYPE (expr); - poly_int64 off0, off1; - HOST_WIDE_INT st; - tree orig_expr = expr; - - STRIP_NOPS (expr); - - type = TREE_TYPE (expr); - code = TREE_CODE (expr); - *offset = 0; - - switch (code) - { - case POINTER_PLUS_EXPR: - case PLUS_EXPR: - case MINUS_EXPR: - op0 = TREE_OPERAND (expr, 0); - op1 = TREE_OPERAND (expr, 1); - - op0 = strip_offset_1 (op0, false, false, &off0); - op1 = strip_offset_1 (op1, false, false, &off1); - - *offset = (code == MINUS_EXPR ? off0 - off1 : off0 + off1); - if (op0 == TREE_OPERAND (expr, 0) - && op1 == TREE_OPERAND (expr, 1)) - return orig_expr; - - if (integer_zerop (op1)) - expr = op0; - else if (integer_zerop (op0)) - { - if (code == MINUS_EXPR) - expr = fold_build1 (NEGATE_EXPR, type, op1); - else - expr = op1; - } - else - expr = fold_build2 (code, type, op0, op1); - - return fold_convert (orig_type, expr); - - case MULT_EXPR: - op1 = TREE_OPERAND (expr, 1); - if (!cst_and_fits_in_hwi (op1)) - return orig_expr; - - op0 = TREE_OPERAND (expr, 0); - op0 = strip_offset_1 (op0, false, false, &off0); - if (op0 == TREE_OPERAND (expr, 0)) - return orig_expr; - - *offset = off0 * int_cst_value (op1); - if (integer_zerop (op0)) - expr = op0; - else - expr = fold_build2 (MULT_EXPR, type, op0, op1); - - return fold_convert (orig_type, expr); - - case ARRAY_REF: - case ARRAY_RANGE_REF: - if (!inside_addr) - return orig_expr; - - step = array_ref_element_size (expr); - if (!cst_and_fits_in_hwi (step)) - break; - - st = int_cst_value (step); - op1 = TREE_OPERAND (expr, 1); - op1 = strip_offset_1 (op1, false, false, &off1); - *offset = off1 * st; - - if (top_compref - && integer_zerop (op1)) - { - /* Strip the component reference completely. */ - op0 = TREE_OPERAND (expr, 0); - op0 = strip_offset_1 (op0, inside_addr, top_compref, &off0); - *offset += off0; - return op0; - } - break; - - case COMPONENT_REF: - { - tree field; - - if (!inside_addr) - return orig_expr; - - tmp = component_ref_field_offset (expr); - field = TREE_OPERAND (expr, 1); - if (top_compref - && cst_and_fits_in_hwi (tmp) - && cst_and_fits_in_hwi (DECL_FIELD_BIT_OFFSET (field))) - { - HOST_WIDE_INT boffset, abs_off; - - /* Strip the component reference completely. */ - op0 = TREE_OPERAND (expr, 0); - op0 = strip_offset_1 (op0, inside_addr, top_compref, &off0); - boffset = int_cst_value (DECL_FIELD_BIT_OFFSET (field)); - abs_off = abs_hwi (boffset) / BITS_PER_UNIT; - if (boffset < 0) - abs_off = -abs_off; - - *offset = off0 + int_cst_value (tmp) + abs_off; - return op0; - } - } - break; - - case ADDR_EXPR: - op0 = TREE_OPERAND (expr, 0); - op0 = strip_offset_1 (op0, true, true, &off0); - *offset += off0; - - if (op0 == TREE_OPERAND (expr, 0)) - return orig_expr; - - expr = build_fold_addr_expr (op0); - return fold_convert (orig_type, expr); - - case MEM_REF: - /* ??? Offset operand? */ - inside_addr = false; - break; - - default: - if (ptrdiff_tree_p (expr, offset) && maybe_ne (*offset, 0)) - return build_int_cst (orig_type, 0); - return orig_expr; - } - - /* Default handling of expressions for that we want to recurse into - the first operand. */ - op0 = TREE_OPERAND (expr, 0); - op0 = strip_offset_1 (op0, inside_addr, false, &off0); - *offset += off0; - - if (op0 == TREE_OPERAND (expr, 0) - && (!op1 || op1 == TREE_OPERAND (expr, 1))) - return orig_expr; - - expr = copy_node (expr); - TREE_OPERAND (expr, 0) = op0; - if (op1) - TREE_OPERAND (expr, 1) = op1; - - /* Inside address, we might strip the top level component references, - thus changing type of the expression. Handling of ADDR_EXPR - will fix that. */ - expr = fold_convert (orig_type, expr); - - return expr; -} - /* Strips constant offsets from EXPR and stores them to OFFSET. */ tree strip_offset (tree expr, poly_uint64_pod *offset) { - poly_int64 off; - tree core = strip_offset_1 (expr, false, false, &off); - *offset = off; - return core; + tree core, toff; + split_constant_offset (expr, &core, &toff); + gcc_assert (!TYPE_UNSIGNED (TREE_TYPE (toff))); + if (tree_fits_poly_int64_p (toff)) + { + *offset = tree_to_poly_int64 (toff); + return core; + } + *offset = 0; + return expr; } /* Returns variant of TYPE that can be used as base for different uses.