From: Richard Biener <rguenther@suse.de>
To: gcc-patches@gcc.gnu.org
Cc: richard.sandiford@arm.com
Subject: [PATCH] tree-optimization/110243 - kill off IVOPTs split_offset
Date: Fri, 16 Jun 2023 14:34:24 +0200 (CEST) [thread overview]
Message-ID: <20230616123424.B38AC1330B@imap2.suse-dmz.suse.de> (raw)
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
next reply other threads:[~2023-06-16 12:34 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-16 12:34 Richard Biener [this message]
2023-06-19 18:32 ` Jeff Law
2023-06-19 20:34 ` Richard Sandiford
2023-06-20 7:36 ` Richard Biener
2023-06-20 20:48 ` Richard Sandiford
2023-06-21 9:14 ` Richard Biener
2023-06-21 10:36 ` Richard Biener
2023-06-21 11:13 ` Richard Sandiford
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230616123424.B38AC1330B@imap2.suse-dmz.suse.de \
--to=rguenther@suse.de \
--cc=gcc-patches@gcc.gnu.org \
--cc=richard.sandiford@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).