This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] fold &b[1] == &b[1U]


Hi!

This patch ajusts the previous patch for PR15791 to handle mixed
signdness of constant array offsets.

Bootstrapped and regtested on x86_64-unknown-linux-gnu.

Ok for mainline?

In general, if having &b[i], the C frontend creates
&b + (int *)(i*4)  (for int b[]), and the pointer offset will
be unsigned.  So, is it correct to always cast ARRAY_REF offsets
to unsigned?  Is &b[i] + j always the same as &b[(unsigned)i+(unsigned)j]?
I mean, in the semantics of the middle-end.

If yes, the patch can probably be simplified to unconditionally create
a comparison of the indices casted to unsigned.

Thanks,
Richard.

2005-02-14  Richard Guenther  <rguenth@gcc.gnu.org>

	* fold-const.c (fold): If folding comparisons of ARRAY_REF,
	for constant offset(s) try to match the offset types, if
	possible.

	* gcc.dg/tree-ssa/pr15791-6.c: New testcase.
	* g++.dg/tree-ssa/pr15791-6.C: Likewise.


Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.502
diff -u -r1.502 fold-const.c
--- fold-const.c	3 Feb 2005 06:44:34 -0000	1.502
+++ fold-const.c	9 Feb 2005 10:15:13 -0000
@@ -8342,6 +8400,30 @@
 		offset0 = build_int_cst (TREE_TYPE (offset1), 0);
 	      else if (offset1 == NULL_TREE)
 		offset1 = build_int_cst (TREE_TYPE (offset0), 0);
+	      else if (TREE_TYPE (offset0) != TREE_TYPE (offset1))
+		{
+		  tree new;
+
+		  /* Try to convert one constant integer offset to the
+		   * type of the other offset, if possible.  */
+		  if (TREE_CODE (offset0) == INTEGER_CST
+		      && ! (TYPE_UNSIGNED (TREE_TYPE (offset1))
+			    && tree_int_cst_sgn (offset0) < 0))
+		    {
+		      new = fold_convert_const_int_from_int (TREE_TYPE (offset1), offset0);
+		      if (! TREE_CONSTANT_OVERFLOW (new))
+			offset0 = new;
+		    }
+		  if (TREE_TYPE (offset0) != TREE_TYPE (offset1)
+		      && TREE_CODE (offset1) == INTEGER_CST
+		      && ! (TYPE_UNSIGNED (TREE_TYPE (offset0))
+			    && tree_int_cst_sgn (offset1) < 0))
+		    {
+		      new = fold_convert_const_int_from_int (TREE_TYPE (offset0), offset1);
+		      if (! TREE_CONSTANT_OVERFLOW (new))
+			offset1 = new;
+		    }
+		}

 	      if (TREE_TYPE (offset0) == TREE_TYPE (offset1))
 		return fold (build2 (code, type, offset0, offset1));


/* { dg-do link } */

void link_error ();

int main ()
{
  struct { int b[2]; } x;
  int b[2];
  if (&b[1U] != &b[1])
    link_error ();
  if (&b[0U] != b)
    link_error ();
  if (b == &b[2U])
    link_error ();
  if (&x.b[1] == &x.b[0U])
    link_error ();
  if (x.b != &x.b[0U])
    link_error ();
  if (&x.b[1U] == x.b)
    link_error ();
  if (&b[1] != &b[1U])
    link_error ();
  return 0;
}



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]