public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
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

             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).