This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] fold &b[1] == &b[1U]
- From: Richard Guenther <rguenth at tat dot physik dot uni-tuebingen dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 14 Feb 2005 10:50:40 +0100 (CET)
- Subject: [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;
}