From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.de 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) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1686918864; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type; bh=PF3EugdzzL4ylQQGVrH+ONVaBuRnRIBSsEOo1mpB3kI=; b=ajyqAU+pU/n4P6SsaZwzNqcYV48saFo1NLy9Su9X2BT0A5qo6UA07pTSwa8LVOns6aLKGT MK9Eukr4zJ+R/o2jvtL+oXDmFme6/WN7bC6W4j0/X3F0MCauPzNofdePtgcC0Oqt9nFgxH tsUgxTvoHSVdySkjseZO9DfaSTbnrBw= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1686918864; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type; bh=PF3EugdzzL4ylQQGVrH+ONVaBuRnRIBSsEOo1mpB3kI=; b=cgBCFON83j2+HWP9P0tJG1aZ5xTMQIeJFdk17CAMRYpcCNBkY9xbedpKug3H5zETEq4yFx 4R23mD5pTnQJg+AQ== 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) From: Richard Biener 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 Content-Type: text/plain; charset=US-ASCII 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 List-Id: 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. -- 2.35.3